Node.js: 为什么空闲和准备阶段只在内部使用?

Node.js: why are idle and prepare phases only used internally?

node.js 的 documentation 描述了其底层事件循环的所谓 阶段
它还明确指出 idleprepare 阶段 仅在内部使用

因为node.js的事件循环是libuv的libuv, it goes without saying that those phases are probably mapped on the idle and prepare句柄之一。
在组织软件中的任务时,它们将有助于获得更大的粒度。特别是,它们是在执行 I/O 回调和轮询阶段之间安排某些事情的唯一方法。
无论如何,它们不是从底层环境导出

这些阶段被禁止的原因是什么,实际上给用户提供了一个明显比 libuv 提供的事件循环最差的事件循环?
有没有其他方法可以按上述方式安排任务?


旁注:这只是好奇。
我曾经同时使用 libuv 和 nodejs 并且我注意到了它,所以我想知道这是否有技术原因或者......好吧,它就是这样设计的,仅此而已,没有特别的原因。

我认为 "forbid" 他们没有特定的理由。而且,它们并不是真的被禁止,只是没有暴露而已。您可以创建一个 Node 插件,它允许您创建空闲和准备句柄,并且根本没有问题。有些事情你必须知道:

  • 空闲句柄有一个糟糕的名字:当循环真正空闲时它们不会 运行。他们 运行 每个循环迭代一次,在计时器之后,如果任何空闲计时器处于活动状态,循环将阻塞 i/o 零秒。所以它们可能很危险,因为如果你不停止它 CPU 就会旋转。

  • 当跨越 C++ <-> JS 边界时调用 process.nextTick 注册的回调(参见对 MakeCallback 的调用)因此 i/o 回调可以延迟运行 稍后。如果您向 JS 公开准备句柄,您将在 C++ 代码中使用 MakeCallback,因此一些 process.nextTick 回调也会与您的准备回调一起被调用。

一般说明:idle、check 和 prepare 句柄以某种方式从 libev(libuv 过去在内部使用)继承而来。 Check 和 prepare 可以在 libuv 与其他库嵌入时使用,空闲句柄有点奇怪,正如我上面提到的。此外,如今 libuv 遵循自己的道路,因此并非 libuv 的所有内容最终都会暴露在 Node 领域。

你可以反问"why do you need idle phase, for example, to be exposed"?您可以只使用 setImmediate().

此外,您为什么要在 I/O 回调和轮询阶段之间执行某些操作,因为您无论如何都不会明确控制这些操作?