单线程
js 是单线程的,但是 js 的引擎不只有一个线程,还可以其他任务线程;
同步和异步任务
同步任务:主线程将代码一步步执行下来,需要等待。
异步任务:引擎会将异步代码放在另任务队列中,等待同步的代码执行完毕,才进行异步代码的执行。
异步实现的几种模式
通过回调形成异步,
就是回调函数不需要等待主函数的结果才会执行, 不会影响主函数后面的代码。列如 ajax 就是通过回调形成的异步,
eg:
function f1(){console.log(1)
}
function f2(){console.log(2)
}
f1()
f2()
// 上述代码是同步的,所以 f2 需要 f1 执行完才会执行。// 改成异步,就是将 f2 改成 f1 的回调。function f1(){console.log(1)
}
function f2(){console.log(2)
}
f1(f2);
//f1(f2())
通过事件驱动
事件驱动机制,就是绑定一个事件,触发该事件后才执行。列如,js 的 addEventListener、jquery 的 on() 方法、定时器、
//js
window.addEventListener("click",function(){alert(1111)
})
window.click();
//jquery
f1.on("success",f2)
function f1(){ajax(url,function(){f1.trigger("success")
})
}
//jquery
f1.on("done",f2);
function f1(){setTimeout(function(){f1.triggle("success");
},1000)
}
// 定时器
var num=1;
setTimeout(function f2(){
num++;
console.log(num);
})
console.log(num);
结论:可以绑定多个监听事件;形成多个回调,利于模块化。但是由于事件驱动,所以很难看出主流程。
发布 / 订阅
事件完全可以理解为“信号”,如果存在一个“信号中心”,某个任务执行完成,就向事件中心”发布“。其他任务则向”信号中心“询问情况。从而知道什么时候自己可以开始。
// 利用 jquery 的插件实现
// 首先,f2 向消息中心订阅 success 事件
jQuery.subscribe('success',f2);
// 对 f1 进行改写:function f1(){ajax(url,() => {
//todo
jQuery.publish('success');// 当 f1 执行完毕后,向消息中心 jQuery 发布 success 事件,从而执行 f2 函数
})
}
//f2 执行完毕后,可以取消订阅
jQuery.unsubscribe('success',f2)
Promise
es6 语法