nextTick() 是如何实际实现的?

问题描述

来自docs

process.nextTick() 在技术上不是事件循环的一部分。反而, nextTickQueue 将在当前操作完成后处理 已完成,无论事件循环的当前阶段如何。在这里一个 操作定义为从底层 C/C++ 的转换 处理程序,并处理需要执行的 JavaScript。

据我所知,只要 C 代码将控制权转移到 JS,就会运行 nextTick() 回调。也就是说,例如,当基于 C (libuv) 的事件循环发现计时器到期时,它会启动其回调,但此时狡猾的 Node 接管了这种情况并执行 nextTickQueue 的回调一开始。

如果我的观点是正确的(如果不正确,请纠正我),那么以下程序的输出对我来说有点令人惊讶:

function forNextTick() {
    console.log('nextTick');
}
function forSetTimeout1() {
    console.log('setTimeout1');
    process.nextTick(forNextTick);
}
function forSetTimeout2() {
    console.log('setTimeout2');
}

setTimeout(forSetTimeout1,0);
setTimeout(forSetTimeout2,0);

输出

setTimeout1
nextTick
setTimeout2

这是 Saul Ibarra Coretge speaking 的摘录:

在节点中,一个节点计时器不是一个 libuv 计时器,因为我明白 这会给垃圾收集器带来太大的压力,所以他们 合并。如果两个计时器同时到期,则它们由一个 单个 libuv 定时器。

因此,如果我们有两个同时运行的 JS 计时器,则它们的回调应该同时运行,作为一个 libuv 计时器回调。我更希望 Node 执行 forSetTimeout1forSetTimeout2,然后将控制权返回给 Event Loop。当后者返回时,Node 运行 nextTick

这是否意味着 Node 不仅在 JS 代码获得控制权时而且在后续的 JS 回调(操作)完成时都会执行 nextTickQueue 回调?

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)