本例中Node的执行顺序是什么

What's the Node's execution order in this example

在 Node JS 中展示 setImmediate 函数功能的常见示例是以下代码

console.log('1');
setImmediate(() => console.log('2'));
console.log('3');

计算结果为

1
3
2

据我所知,setImmediate 回调在事件循环的 check 阶段执行

但是我不明白哪里适合获取新的顺序指令?我们能保证 Node 在执行检查阶段之前获取并执行 console.log('3') 并因此在 2 之前打印 3 吗?如果是这样 - 在到达 check 阶段之前 Node 会执行多少条这样的指令?

However I don't understand where fetching new, sequential instruction fits there?

不需要获取任何新的东西,因为所有的指令都必须在那个时候加载,因为我们已经在执行它们了!

  1. 确定你的代码应该运行
  2. 您的代码(全部 3 行)运行s
  3. 进入事件循环并检查还有什么要做
  4. 确定回调应该运行
  5. 回调(所有“1 行”)运行s
  6. ...

Are we guaranteed that Node will fetch and execute console.log('3') BEFORE executing the check phase and therefore print 3 before 2?

是的。

If so - how many such instruction would Node execute before reaching check phase?

无限多。

JavaScript 是单线程*,没有什么可以抢占您的代码(Ctrl+C 除外)。

所以,下面的代码将永远输出 3 永远不会 到达 2**:

console.log('1');
setImmediate(() => console.log('2'));
while (true) {
  console.log('3');
}
1
3
3
3
3
... (forever)

类似地,下面的代码将永远打印 2A 并且永远不会到达 2B:

console.log('1');
setImmediate(() => {
  while (true) {
    console.log('2A');
  }
});
setImmediate(() => console.log('2B'));
console.log('3');
1
3
2A
2A
2A
2A
... (forever)

(如果您要将 setImmediate(() => console.log('2B')); 移动到第一个回调中而不是将其放在它下面,同样适用。)

*: 是的,node.js 中有工作线程,浏览器中有服务工作者,但它们生活在自己的环境中。

**:...在此过程中消耗了一个 CPU 核心的 100%,并且不对任何事件或信号做出反应,因此请将此视为学术兴趣的示例,而不是你会用真实代码写的东西。