同步任务(synchronous)和异步任务(asynchronous)
- 同步任务是那些没有被引擎挂起、在主线程上排队执行的任务。
- 异步任务是那些被引擎放在一边,不进入主线程、而进入任务队列的任务。
- 只有引擎认为某个异步任务可以执行了(比如 Ajax操作从服务器得到了结果),该任务(采用回调函数的形式)才会进入主线程执行。排在异步任务后面的代码,不用等待异步任务结束会马上运行,也就是说,异步任务不具有”堵塞“效应。
任务队列和事件循环
- JavaScript 运行时,除了一个正在运行的主线程(JavaScript 设计之初即是单线程),引擎还提供任务队列(task queue)。
- 首先,主线程会去执行所有的同步任务。
- 同步任务全部执行完,就会去看任务队列里面的异步任务。如果满足条件,异步任务重新进入主线程,并执行对应的回调函数。
- 如果一个异步任务没有回调函数,就不会进入任务队列。
- 事件循环(Event Loop)就是用来检查异步任务是不是可以进入主线程,事件循环是一个程序结构,用于等待和发送消息和事件。
异步操作的模式
- 回调函数
- 事件监听 异步任务的执行不取决于代码的顺序,而取决于某个事件是否发生。
- 发布/订阅
事件完全可以理解成”信号“,如果存在一个”信号中心“,某个任务执行完成,就向信号中心”发布“(publish)一个信号,其他任务可以向信号中心”订阅“(subscribe)这个信号,从而知道什么时候自己可以开始执行。这就叫做”发布/订阅模式”(publish-subscribe pattern),又称“观察者模式”(observer pattern)。
jQuery.subscribe('done', f2);
function f1() {
setTimeout(function () {
// ...
jQuery.publish('done');
}, 1000);
}
jQuery.unsubscribe('done', f2);
异步操作的流程控制
串行执行
一个任务完成以后,再执行另一个
并行执行
所有异步任务同时执行,等到全部完成以后,才执行final函数。
并行与串行的结合
设置一个门槛,每次最多只能并行执行n个异步任务,这样就避免了过分占用系统资源。