微任务和 nextTicks 有一个重要的语义,这取决于 Node 版本。
在 Node v11 之前,nextTick 队列在事件循环的每个阶段之间执行(计时器、I/O、立即数、关闭处理程序是四个阶段)。因此,在 Node v11 之前,promise 回调也在事件循环的每个阶段之间执行。 (我在这里详细写了这一点:https://blog.insiderattack.net/promises-next-ticks-and-immediates-nodejs-event-loop-part-3-9226cbe7a6aa https://blog.insiderattack.net/promises-next-ticks-and-immediates-nodejs-event-loop-part-3-9226cbe7a6aa)
然而,从 Node v11 开始,事件循环跳转到microtask
每当有一个队列microtask
作为程序执行的一部分添加到微任务队列中。您可以使用以下代码片段进行实验。这同样适用于 nextTick 队列。你可以在这里阅读更多:https://blog.insiderattack.net/new-changes-to-timers-and-microtasks-from-node-v11-0-0-and-above-68d112743eb3 https://blog.insiderattack.net/new-changes-to-timers-and-microtasks-from-node-v11-0-0-and-above-68d112743eb3
setImmediate(() => console.log('timeout1'));
setImmediate(() => {
console.log('timeout2')
Promise.resolve().then(() => console.log('promise'))
});
setImmediate(() => console.log('timeout3'));
setImmediate(() => console.log('timeout4'));
上述代码的输出根据 Node.js 版本的不同而变化,如下所示:
$ node -v
v10.19.0
$ node test.js
timeout1
timeout2
timeout3
timeout4
promise
$ nvm use 11
Now using node v11.15.0 (npm v6.7.0)
$ node test.js
timeout1
timeout2
promise
timeout3
timeout4
因此重要的是要知道: nextTicks
and microtasks
在 Node 版本 >=11 中具有更高的优先级,因为它们有机会在事件循环的当前阶段内进行处理。但在早期的 Node 版本中,nextTicks
and microtasks
在循环的每个阶段结束时执行。
顺便说一句,重要的是要知道microtasks
队列是的一部分v8
引擎并且不在 Node.js 运行时维护。然而,Node.js 事件循环指示v8
运行所有microtasks
,一旦 Node.js 完成nextTick
队列。因此,promise 回调会在之后执行nextTick
queue.