3

根据Node.js 文档,当事件循环进入其轮询阶段且轮询队列不为空时,轮询队列中的回调应在事件循环进一步进入其检查阶段之前执行。

然而,实际上,相反的情况会发生,即如果在事件循环进入轮询阶段时轮询和检查 (setImmediate) 队列都不是空的,则检查 (setImmediate) 队列中的回调总是在之前执行来自轮询队列的回调。

这是为什么?我在Node.js 文档中缺少什么?

这里遵循示例代码和来自Node.js 文档的引用。

来自Node.js 文档的引用:

轮询阶段有两个主要功能:
    1.计算它应该阻塞和轮询I/O的时间,然后
    2.处理轮询队列中的事件。

当事件循环进入轮询阶段并且没有安排定时器时,
将发生以下两种情况之一:
(a) - 如果轮询队列不为空,事件循环将迭代 通过其同步执行它们的回调队列 直到队列已用完, 或达到系统相关的硬限制。
(b) - 如果轮询队列为空,将会发生另外两种情况之一: - 如果脚本已由 setImmediate() 安排, 事件循环将结束轮询阶段并继续检查阶段 执行那些预定的脚本。 - 如果脚本没有被 setImmediate() 调度, 事件循环将等待回调被添加到队列中, 然后立即执行它们。 一旦轮询队列为空,事件循环将检查计时器 已达到时间阈值。如果一个或多个计时器准备就绪, 事件循环将回到计时器阶段 执行这些计时器的回调。

示例代码:

const fs = require(`fs`);

console.log(`START`);

const readFileCallback = () => {
  console.log(`readFileCallback`);
};
fs.readFile(__filename, readFileCallback);

const setImmediateCallback = () => {
  console.log(`setImmediateCallback`);
};
setImmediate(setImmediateCallback);

// Now follows the loop long enough to give the fs.readFile enough time
// to finish its job and to place its callback (the readFileCallback)
// into the event-loop's poll phase queue before the "main" synchronous part
// of the this code finishes.
for (let i = 1; i <= 10000000000; i++) {}

console.log(`END`);
// So when the event-loop starts its first tick there should be two callbacks
// waiting:
//   (1) the readFileCallback (in the poll queue)
//   (2) the setImmediateCallback (in the check queue)
// Now according to the Node.js DOCs, of these two waiting callbacks
// the readFileCallback should execute first, but the opposite
// is actually happening, that is setImmediateCallback executes first.
4

0 回答 0