为什么在I/O回调之后执行Node.js setImmediate? [英] Why Node.js setImmediate executes after I/O callbacks?

查看:78
本文介绍了为什么在I/O回调之后执行Node.js setImmediate?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

As new member, I'm unable to comment on topics, that's why I had to create a new topic. But in this way, I can clarify the problem, so hopefully you guys can help me.

我已经阅读了很多有关Node.js事件循环的信息.我根据以下材料对我的理解进行了塑造:

I have read quite a lot about Node.js Event Loop. And I have shaped my understanding of it based on following materials:

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

(请随时建议其他内容翔实且准确的材料)

(Please feel free to suggest other materials which are informative and accurate)

尤其是第三个链接,使我有了更好的理解.但是请记住,我无法理解以下代码的事件循环行为:

Especially the third link, has given me a better understanding. But keeping that in mind, I'm unable to understand Event Loop behavior for the following code:

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");

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

Surprisingly, for me output is as follow:

LOGGER  
FIRST STAT  
LAST STAT  
IMMEDIATE

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

记住事件循环关系图,我想流程应该如下:

Keeping the Event Loop Diagram in mind, I guess flow should be as follow:

  1. 解释器首先启动两个统计操作.
  2. 解释器在setImmedate队列中排队setImmedate回调(事件)
  3. 调用堆栈记录记录器
  4. I/O轮询阶段之前的所有事件队列均为空,因此事件循环(EL)继续运行
  5. 在I/O轮询阶段,EL收集事件并在运行完成的I/O处理程序"阶段将两个fs.stat回调入队
  6. EL检查Check阶段,并运行setImmediate回调
  7. 这轮EL结束,第二轮开始
  8. 在运行完成的I/O处理程序"中,EL运行两个回调(它们的顺序可以确定)

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

Question 1: Which part of my analysis/prediction is wrong?

问题2:事件循环在哪一点开始起作用?它是否从应用程序的开头(即阶段1)开始?还是在解释器读取了整个代码之后开始,所有同步任务都在调用堆栈中完成,并且调用堆栈需要更多的任务,即在第3-4阶段之间?

Question 2: At which point, does Event Loop start working? Does it start from the beginning of the app (i.e. stage 1)? or does it start once the whole code is read by interpreter, all sync tasks are done within Call Stack, and Call Stack needs more task, i.e. between stage 3-4?

预先感谢

推荐答案

setImmediate =执行而无需等待任何I/O

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

安排在I/O事件的回调之后 的立即"执行.返回一个即时值,用于clearImmed

Schedules the "immediate" execution of the callback after I/O events' callbacks. Returns an Immediate for use with clearImmed

步骤:

  1. First stat的回调在I/O队列中排队
  2. 最后一个统计信息的回调在I/O队列中排队
  3. 即时通讯的回调已在即时通讯队列中排队
  4. LOGGER
  5. 如果I/O操作(在1和2中)已完成,则将1和/或2中的回调标记为可以执行
  6. 一个接一个地执行就绪的回调(首先是微调,然后是I/O,最后是立即执行).在您的情况下:
  1. callback for First stat is queued in I/O queue
  2. callback for Last stat is queued in I/O queue
  3. callback for immediate is queued in Immediates queue
  4. LOGGER
  5. If I/O operations (in 1 and 2) are finished the callbacks in 1 and/or 2 are marked as ready to execute
  6. Execute the ready callbacks one by one (first timmer, then I/O, finally immediates). In your case:
  1. 首次统计
  2. 最新统计
  3. LOGGER

如果I/O没有以 5结尾.,则在FIRST STAT和LAST STAT之前执行LOGGER.

In the case that I/O does'nt ends at 5. then LOGGER were execute before FIRST STAT and LAST STAT.

另请参阅: 查看全文

登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆