了解Node.Js事件循环执行

时间:2019-03-07 10:07:05

标签: node.js event-loop

我是node.js的新手,正在尝试了解事件循环。众所周知,process.nextTick()不是事件循环的一部分。那么,有人可以解释在事件循环开始之前是否将执行process.nextTick()回调吗?请在说明中包括不同的node.js事件循环阶段状态。


     process.nextTick(() => {
        console.log("3")
        console.log('nextTick');
      });

    console.log("close")

    setTimeout(() => {
        console.log("1")
        console.log('timeout');
      }, 0);

      setImmediate(() => {
        console.log("2")
        console.log('immediate');
      });

1 个答案:

答案 0 :(得分:2)

让我尝试

您可以在此处找到有关节点事件循环的简短说明(16分钟):
https://www.youtube.com/watch?v=PNa9OMajw9w&list=PLw5h0DiJ-9PCIrjcodoAZdA4CcCarnCOo&index=2

最好的解释是官方指南(由@estus提及):
https://nodejs.org/en/docs/guides/event-loop-timers-and-nexttick/

有关更多详细说明,请查看以下系列博客文章:
https://jsblog.insiderattack.net/event-loop-and-the-big-picture-nodejs-event-loop-part-1-1cb67a182810

根据{{​​3}}:

  

您可能已经注意到process.nextTick()并未显示在图中,即使它是异步API的一部分也是如此。这是因为process.nextTick()从技术上讲不是事件循环的一部分。相反,无论当前事件循环的当前阶段如何,都将在当前操作完成之后处理nextTickQueue。
  回顾一下我们的图,在给定阶段中每次调用process.nextTick()时,传递给process.nextTick()的所有回调都将在事件循环继续之前得到解决。   

因此, process.nextTick()回调将在每个事件循环的滴答处执行,而不是在事件循环开始之前执行。
让我用这个简单的程序演示一下:

 process.nextTick(() => console.log("process.nextTick before"));
 const intervalId = setInterval(() => {
   console.log("interval");
   process.nextTick(() => console.log("process.nextTick from interval"));
 }, 1000);
 process.nextTick(() => console.log("process.nextTick after"));

 setTimeout(() => {
   clearInterval(intervalId);
   console.log("Interval was cleared - nothing more to run - the event loop will stop - program will stop");
 }, 5000);

这是输出:

process.nextTick before
process.nextTick after
interval
process.nextTick from interval
interval
process.nextTick from interval
interval
process.nextTick from interval
interval
process.nextTick from interval
Interval was cleared - nothing more to run - the event loop will stop - program will stop

说明:

  • process.nextTick(()=> console.log(“ interval.nextTick from interval”)); 将回调添加到 nextTickQueue (也称为< strong>微任务队列)。因此,文本'来自间隔的process.nextTick'将在第一个文本'interval'之后但在下一个文本'interval'之前打印。来自微任务队列的所有回调将在事件循环继续到下一阶段之前运行(请参阅官方指南中的上述引用)。
  • 在第一个 interval 文本之前打印
  • 文本'process.nextTick''process.nextTick after',因为 nextTickQueue 在事件循环开始之前已被处理。从official guide
      

    Node.js启动时,它将初始化事件循环,处理提供的输入脚本(或放入REPL,本文档未涵盖)可能会进行异步API调用,调度计时器或调用process.nextTick (),然后开始处理事件循环。   

回到您的示例。

这是程序的输出:

close
3
nextTick
1
timeout
2
immediate

说明:

  1. 文本:'close'-首先打印-因为节点已处理了输入脚本
  2. 文本:'3'; 'nextTick'-打印第二个-因为在事件循环开始之前运行了nextTickQueue的回调
  3. 文本:'1'; 'timeout'-第三条-因为由 setTimeout setInterval 安排的回调在 timer 阶段运行-第一阶段
  4. 文本:'2'; 'immediate'-印刷第四-因为由'setImmediate'安排的回调在 check 阶段-第五阶段
  5. 中运行

希望这个长答案能使事情变得清楚。