event-loop-microtask-macrotask

event-loop,microtask,macrotask

文章引用 creeperyyang的blog从Promise来看JavaScript中的Event Loop、Tasks和Microtasks

Node.js的event loop及timer/setImmediate/nextTick

1
2
3
4
5
6
7
8
9
10
11
12
13
14
(function test() {
setTimeout(function() {console.log(4)}, 0);
new Promise(function executor(resolve) {
console.log(1);
for( var i=0 ; i<10000 ; i++ ) {
i == 9999 && resolve();
}
console.log(2);
}).then(function() {
console.log(5);
});
console.log(3);
})()
// 为什么输出结果是1,2,3,5,4而非1,2,3,4,5?

event-loop中每一次loop执行的是:task-> (setTimeout, setImmediate, io…)

在当前”执行栈”的尾部–下一次Event Loop(主线程读取”任务队列”)之前,执行microtask -> (promise, proccess.nextTick())

下面总结几点关于event loop的:

  1. 在浏览器和Node.js中,JS都是以单线程在运行,当前执行栈必然是执行完(为空) 才会进入下个event loop。
  2. process.nextTick和Promise都是microtask,即在进入下个event loop前执行(也可以理解成不是event loop相关的概念)
  3. setTimeout/setImmediate/io是task,会把回调延迟到后面的某个event loop执行。
  4. node.js中event loop分为不同的阶段,每个阶段有自己的任务。

event loop怎么处理tasks和microtasks?

  1. 每个线程有自己的事件循环,所以每个web worker有自己的,所以它才可以独立执行。然而,所有同属一个origin的windows共享一个事件循环,所以它们可以同步交流。
  2. 事件循环不间断在跑,执行任何进入队列的task。
  3. 一个事件循环可以有多个task source,每个task source保证自己的任务列表的执行顺序,但由浏览器在(事件循环的)每轮中挑选某个task source的task。
  4. tasks are scheduled,所以浏览器可以从内部到JS/DOM,保证动作按序发生。在tasks之间,浏览器可能会render updates。从鼠标点击到事件回调需要schedule task,解析html,setTimeout这些都需要。
  5. microtasks are scheduled,经常是为需要直接在当前脚本执行完后立即发生的事,比如async某些动作但不必承担新开task的弊端。microtask queue在回调之后执行,只要没有其它JS在执行中,并且在每个task的结尾。microtask中添加的microtask也被添加到microtask queue的末尾并处理。microtask包括mutation observer callbacks和promise callbacks。
坚持原创技术分享,您的支持将鼓励我继续创作!