根据this answer:
“重要的是要考虑到promise中的then/catch回调是微任务,将在nextTick任务之后执行”
Nodejs文档中提到nextTickQueue将在当前操作完成后被处理,而不管事件循环的当前阶段。这是否意味着resolved promises回调不会在poll阶段或pending callbacks阶段执行?
此外,this video提到有一个queueMicroTask队列,它在事件循环的当前阶段之后处理。所以我现在理解的是:
已解决的promises回调将被添加到queueMicroTask,该queueMicroTask将在nextTickQueue(传递给process.nextTick的回调)之后处理,该队列将在事件循环的当前阶段之后处理。
是这样吗?如果不是请纠正我,我真的很困惑。
2条答案
按热度按时间cbjzeqam1#
微任务和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)
**然而,从Node v11开始,**事件循环会跳转到
microtask
队列,每当microtask
作为程序执行的一部分添加到微任务队列时。您可以使用以下片段进行实验。同样适用于nextTick队列。您可以在这里阅读更多内容:https://blog.insiderattack.net/new-changes-to-timers-and-microtasks-from-node-v11-0-0-and-above-68d112743eb3上述代码的输出根据Node.js版本的不同而变化,如下所示:
因此,重要的是要知道:
nextTicks
和microtasks
在Node版本〉=11中具有更高的优先级,因为它们有机会在事件循环的当前阶段中被处理。但在早期的Node版本中,nextTicks
和microtasks
在循环的每个阶段结束时执行。顺便说一下,重要的是要知道
microtasks
队列是v8
引擎的一部分,并且不在Node.js运行时中维护。但是,一旦Node.js完成nextTick
队列,Node.js事件循环指示v8
运行所有microtasks
。因此,promise回调在nextTick
队列之后执行。cgyqldqp2#
Nodejs文档中提到nextTickQueue将在当前操作完成后被处理,而不管事件循环的当前阶段。这是否意味着resolved promises回调不会在poll阶段或pending callbacks阶段执行?
这肯定是一种模棱两可的信息。它们可以在任何一个阶段运行,但它们并不排他于特定的阶段。
已解决的promises回调将被添加到queueMicroTask,该queueMicroTask将在nextTickQueue(传递给process.nextTick的回调)之后处理,该队列将在事件循环的当前阶段之后处理。
不是在每个阶段结束时,它可能发生在任何阶段的任何时候(据我所知)。
假设你有两个计时器已经过期,并且你处于事件循环的计时器过期阶段。这意味着在这个阶段有两个回调要处理。让我们假设第一个计时器在已经解析的promise上调用
then
。(它可以马上到达它)。如果这是在阶段结束时发射的,那么第二个定时器回调会在之前运行,因为它还没有结束。这里真正发生的是,第一个计时器回调运行并将回调添加到微任务队列中,该队列在回调完成后和继续当前事件循环阶段之前被消耗。
可以运行的示例: