Javascript 与Node.js中的事件循环调用的确切代码混淆
我在学习Node.js,并观看了关于事件循环执行哪些代码的视频。下面是代码片段:Javascript 与Node.js中的事件循环调用的确切代码混淆,javascript,node.js,Javascript,Node.js,我在学习Node.js,并观看了关于事件循环执行哪些代码的视频。下面是代码片段: const fs = require('fs') setTimeout(()=>console.log("Timer 1 finished"), 0); setImmediate(()=>console.log("Immediate 1 finished")); fs.readFile("test-file.txt", ()=>{ console.log("I/O finished"); con
const fs = require('fs')
setTimeout(()=>console.log("Timer 1 finished"), 0);
setImmediate(()=>console.log("Immediate 1 finished"));
fs.readFile("test-file.txt", ()=>{
console.log("I/O finished");
console.log("----------");
setTimeout(()=>console.log("Timer 2 finished"), 0);
setTimeout(()=>console.log("Timer 3 finished"), 3000);
})
console.log("Hello from the top-level code")
问题是为什么在事件循环中调用readFile回调中的setTimeout和setImmediate,但以下代码:
setTimeout(()=>console.log("Timer 1 finished"), 0);
setImmediate(()=>console.log("Immediate 1 finished"));
未在事件循环中运行。这句话是Node.js课程的作者说的,但他没有解释原因。他错了吗
但这段代码…不是在事件循环中运行的
这在字面上是正确的,但这几乎是一个语义问题,并不是真正有用的区分。您可以将其视为顶级代码在循环的第一个过程中运行,就好像它是一个立即触发的计时器回调一样。但报告确实指出,这是在事件循环之前,而不是在事件循环期间:
┌───────────────────────────┐
┌─>│ timers │
│ └─────────────┬─────────────┘
│ ┌─────────────┴─────────────┐
│ │ pending callbacks │
│ └─────────────┬─────────────┘
│ ┌─────────────┴─────────────┐
│ │ idle, prepare │
│ └─────────────┬─────────────┘ ┌───────────────┐
│ ┌─────────────┴─────────────┐ │ incoming: │
│ │ poll │<─────┤ connections, │
│ └─────────────┬─────────────┘ │ data, etc. │
│ ┌─────────────┴─────────────┐ └───────────────┘
│ │ check │
│ └─────────────┬─────────────┘
│ ┌─────────────┴─────────────┐
└──┤ close callbacks │
└───────────────────────────┘
当Node.js启动时,它会初始化事件循环,处理提供的输入脚本(或放入REPL,本文档中未介绍),该脚本可能会进行异步API调用、调度计时器或调用process.nextTick()
,然后开始处理事件循环
(我的重点)
但同样,这是一个真正没有什么区别的区别
请注意,以这种方式运行的代码不仅仅是您在问题的这一部分中引用的行;稍后再谈
大多数情况下,您可以认为所有JavaScript代码都在事件循环中运行,但Node.js具有上述区别,并且还具有process.nextTick
,其中:
…在技术上不是事件循环的一部分。相反,无论事件循环的当前阶段如何,都将在当前操作完成后处理nextTickQueue
。这里,操作被定义为从底层C/C++处理程序的转换,并处理需要执行的JavaScript
这是一个非常特定于Node.js的东西。请注意,虽然他们说它在技术上处于事件循环之外,但它仍然在事件循环期间运行,只是nextTick
没有将任务添加到主循环中,而是将其添加到另一个队列中,该队列将尽快处理,而不管事件循环处于哪个阶段
为了更好地理解,这一整页都值得一读
关于示例中的代码在何时运行,上面链接的文档提供了Node.js事件循环的方便图表:
┌───────────────────────────┐
┌─>│ timers │
│ └─────────────┬─────────────┘
│ ┌─────────────┴─────────────┐
│ │ pending callbacks │
│ └─────────────┬─────────────┘
│ ┌─────────────┴─────────────┐
│ │ idle, prepare │
│ └─────────────┬─────────────┘ ┌───────────────┐
│ ┌─────────────┴─────────────┐ │ incoming: │
│ │ poll │<─────┤ connections, │
│ └─────────────┬─────────────┘ │ data, etc. │
│ ┌─────────────┴─────────────┐ └───────────────┘
│ │ check │
│ └─────────────┬─────────────┘
│ ┌─────────────┴─────────────┐
└──┤ close callbacks │
└───────────────────────────┘
- 答:在初始评估期间,“在”事件循环之前
- B:在事件循环的“计时器”阶段
- C:在事件循环的“检查”阶段
- D:在“轮询”阶段(或者可能是
的“挂起回调”阶段)延迟回调,我不知道是哪个readFile