为什么Node.js setImmediate在I / O回调后执行?
作为新成员,我无法评论主题,这就是为什么我必须创建一个新主题。但通过这种方式,我可以澄清问题,所以希望你们能帮助我。
我已经阅读了很多关于Node.js事件循环的内容。我根据以下材料塑造了对它的理解:
Node.js Event Loop What the heck is the event loop anyway? Why setImmediate() execute before fs.readFile() in Nodejs Event Loop's works?
(请随时提供其他信息和准确的材料)
特别是第三个环节,给了我更好的理解。但请牢记这一点,我无法理解以下代码的事件循环行为:
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
screenshot of my terminal, showing output as well as node version screenshot of output from online code compiler rextester
保持事件循环Diagram,我想流量应如下:
- 口译员首先开始了两次开始运营。
- 解释器在setImmedate队列中对setImmedate回调(事件)进行入队
- 调用堆栈记录记录器
- I / O轮询阶段之前的所有事件队列都为空,因此事件循环(EL)继续运行
- 在I / O轮询阶段,EL收集事件并将“运行完成的I / O处理程序”阶段中的fs.stat回调排入队列
- EL检查Check阶段,并运行setImmediate回调
- 这轮EL结束,第二轮开始
- 在“运行完成的I / O处理程序”中,EL运行两个回调(它们的顺序可以是onn-determinstic)
问题1:我的分析/预测的哪一部分是错误的?
问题2:此时,Event Loop是否开始工作?它是从应用程序的开头(即第1阶段)开始的吗?或者在解释器读取整个代码后启动,所有同步任务都在Call Stack中完成,而Call Stack需要更多任务,即在3-4阶段之间?
提前致谢,
回答如下:setImmediate = execute without wait any I/O
在https://nodejs/docs/v8.9.3/api/timers.html#timers_setimmediate_callback_args说:
在I / O事件的回调之后安排回调的“立即”执行。返回Immediate以与clearImmed一起使用
脚步:
- 第一个stat的回调在I / O队列中排队
- Last stat的回调在I / O队列中排队
- 立即回调在Immediates队列中排队
- 日志
- 如果I / O操作(在1和2中)完成,则1和/或2中的回调标记为准备执行
- 逐个执行准备好的回调(第一个timmer,然后是I / O,最后是immediates)。在你的情况下: 第一个统计 最后统计 记录仪
如果I / O没有在5.
结束,则LOGGER在FIRST STAT和LAST STAT之前执行。
另见:https://jsblog.insiderattack/timers-immediates-and-process-nexttick-nodejs-event-loop-part-2-2c53fd511bb3#f3dd
为什么Node.js setImmediate在I / O回调后执行?
作为新成员,我无法评论主题,这就是为什么我必须创建一个新主题。但通过这种方式,我可以澄清问题,所以希望你们能帮助我。
我已经阅读了很多关于Node.js事件循环的内容。我根据以下材料塑造了对它的理解:
Node.js Event Loop What the heck is the event loop anyway? Why setImmediate() execute before fs.readFile() in Nodejs Event Loop's works?
(请随时提供其他信息和准确的材料)
特别是第三个环节,给了我更好的理解。但请牢记这一点,我无法理解以下代码的事件循环行为:
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
screenshot of my terminal, showing output as well as node version screenshot of output from online code compiler rextester
保持事件循环Diagram,我想流量应如下:
- 口译员首先开始了两次开始运营。
- 解释器在setImmedate队列中对setImmedate回调(事件)进行入队
- 调用堆栈记录记录器
- I / O轮询阶段之前的所有事件队列都为空,因此事件循环(EL)继续运行
- 在I / O轮询阶段,EL收集事件并将“运行完成的I / O处理程序”阶段中的fs.stat回调排入队列
- EL检查Check阶段,并运行setImmediate回调
- 这轮EL结束,第二轮开始
- 在“运行完成的I / O处理程序”中,EL运行两个回调(它们的顺序可以是onn-determinstic)
问题1:我的分析/预测的哪一部分是错误的?
问题2:此时,Event Loop是否开始工作?它是从应用程序的开头(即第1阶段)开始的吗?或者在解释器读取整个代码后启动,所有同步任务都在Call Stack中完成,而Call Stack需要更多任务,即在3-4阶段之间?
提前致谢,
回答如下:setImmediate = execute without wait any I/O
在https://nodejs/docs/v8.9.3/api/timers.html#timers_setimmediate_callback_args说:
在I / O事件的回调之后安排回调的“立即”执行。返回Immediate以与clearImmed一起使用
脚步:
- 第一个stat的回调在I / O队列中排队
- Last stat的回调在I / O队列中排队
- 立即回调在Immediates队列中排队
- 日志
- 如果I / O操作(在1和2中)完成,则1和/或2中的回调标记为准备执行
- 逐个执行准备好的回调(第一个timmer,然后是I / O,最后是immediates)。在你的情况下: 第一个统计 最后统计 记录仪
如果I / O没有在5.
结束,则LOGGER在FIRST STAT和LAST STAT之前执行。
另见:https://jsblog.insiderattack/timers-immediates-and-process-nexttick-nodejs-event-loop-part-2-2c53fd511bb3#f3dd