千家信息网

nodejs中setTimeout(fn,0)和setImmediate哪个先执行

发表于:2025-01-30 作者:千家信息网编辑
千家信息网最后更新 2025年01月30日,今天就跟大家聊聊有关nodejs中setTimeout(fn,0)和setImmediate哪个先执行,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所
千家信息网最后更新 2025年01月30日nodejs中setTimeout(fn,0)和setImmediate哪个先执行

今天就跟大家聊聊有关nodejs中setTimeout(fn,0)和setImmediate哪个先执行,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。

我们首先看一下下面这段代码

    
setTimeout(()=>{ console.log('setTimeout'); },0)
setImmediate(()=>{ console.log('setImmedate');})

我们执行上面这段代码,会发现输出是不确定的。下面来看一下为什么。

nodejs的事件循环分为几个阶段(phase)。setTimeout是属于定时器阶段,setImmediate是属于check阶段。顺序上定时器阶段是比check更早被执行的。在分析nodejs的setImmediate和setTimeout的文章中已经介绍过这两个函数对应的实现原理。这里就不细说了。其中setTimeout的实现代码里有一个很重要的细节。

                 
after *= 1; // coalesce to number or NaN
if (!(after >= 1 && after <= TIMEOUT_MAX)) {
if (after > TIMEOUT_MAX) {
process.emitWarning(`${after} does not fit into` +
' a 32-bit signed integer.' +
'\nTimeout duration was set to 1.',
'TimeoutOverflowWarning');
}
after = 1; // schedule on next tick, follows browser behavior
}

我们发现虽然我们传的超时时间是0,但是0不是合法值,nodejs会把超时时间变成1。这就是导致上面的代码输出不确定的原因。我们分析一下这段代码的执行过程。nodejs启动的时候,会编译执行上面的代码,开始一个定时器,挂载一个setImmediate节点在队列。然后进入libuv的事件循环,然后执行定时器阶段,libuv判断从开启定时器到现在是否已经过去了1毫秒,是的话,执行定时器回调,否则执行下一个节点,执行完其他阶段后,会执行check阶段。这时候就会执行setImmediate的回调。所以,一开始的那段代码的输出结果是取决于启动定时器的时间到libuv执行定时器阶段是否过去了1毫秒。

看完上述内容,你们对nodejs中setTimeout(fn,0)和setImmediate哪个先执行有进一步的了解吗?如果还想了解更多知识或者相关内容,请关注行业资讯频道,感谢大家的支持。

0