2

作为新成员,我无法对主题发表评论,这就是为什么我必须创建一个新主题。但是通过这种方式,我可以澄清问题,所以希望你们能帮助我。

我已经阅读了很多关于 Node.js 事件循环的内容。我根据以下材料形成了我对它的理解:

Node.js 事件循环 事件循环
到底是什么?
为什么在 Nodejs Event Loop 的作品中 setImmediate() 在 fs.readFile() 之前执行?

(请随时建议其他信息丰富且准确的材料)

尤其是第三个环节,让我有了更好的理解。但请记住这一点,我无法理解以下代码的事件循环行为:

var fs = require('fs');
var pos = 0;

fs.stat(__filename, function() {
 console.log(++pos + " FIRST STAT");
});

fs.stat(__filename, function() {
 console.log(++pos + " LAST STAT");
});

setImmediate(function() {
 console.log(++pos + " IMMEDIATE")
})

console.log(++pos + "LOGGER");

令人惊讶的是,对我来说输出如下:

LOGGER  
FIRST STAT  
LAST STAT  
IMMEDIATE

我的终端的屏幕截图,显示输出以及
来自在线代码编译器 rextester.com 的输出的节点版本屏幕截图

记住事件循环,我猜流程应该如下:

  1. 解释器首先启动两个 stat 操作。
  2. 解释器入队 setImmedate 队列中的 setImmedate 回调(事件)
  3. 调用堆栈记录记录器
  4. I/O Poll 阶段之前的所有事件队列都是空的,所以 Event Loop(EL) 继续进行
  5. 在 I/O 轮询阶段,EL 收集事件并将 fs.stat 回调排入“运行完成的 I/O 处理程序”阶段
  6. EL 检查 Check 阶段,并运行 setImmediate 回调
  7. 本轮EL结束,第二轮开始
  8. 在“运行完成的 I/O 处理程序”中,EL 运行两个回调(它们的顺序可以是 onn-determinstic)

问题 1:我的分析/预测的哪一部分是错误的?

问题 2:Event Loop 什么时候开始工作?它是否从应用程序的开头(即第 1 阶段)开始?还是在解释器读取整个代码后启动,所有同步任务都在调用堆栈内完成,调用堆栈需要更多任务,即在阶段 3-4 之间?

提前致谢,

4

1 回答 1

0

setImmediate = 执行不等待任何 I/O

https://nodejs.org/docs/v8.9.3/api/timers.html#timers_setimediate_callback_args中说:

在I/O 事件的回调之后安排回调的“立即”执行。返回一个与 clearImmed 一起使用的立即数

脚步:

  1. First stat 的回调在 I/O 队列中排队
  2. Last stat 的回调在 I/O 队列中排队
  3. 即时回调在即时队列中排队
  4. 记录器
  5. 如果 I/O 操作(在 1 和 2 中)完成,则在 1 和/或 2 中的回调被标记为准备好执行
  6. 一个一个地执行准备好的回调(第一个定时器,然后是 I/O,最后是立即数)。在你的情况下:
    1. 第一个统计
    2. 最后统计
    3. 记录器

在 I/O 没有结束的情况下,5.LOGGER 在 FIRST STAT 和 LAST STAT 之前执行。

另见:https ://jsblog.insiderattack.net/timers-immediates-and-process-nexttick-nodejs-event-loop-part-2-2c53fd511bb3#f3dd

于 2017-12-25T18:06:51.940 回答