- 此问题在此处已有答案**:
SetTimeout And SetImmediate with console.log(2个答案)
19小时前关门了。
示例
// test.js
setTimeout(() => console.log('hello'), 0)
setImmediate(() => console.log('world'))
只需在Intel MacBook Pro上通过节点v12.12.12运行node test.js
。有时输出为:
hello
world
有时是:
world
hello
我的理解
v8首先运行代码,当遇到setTimeout
时,在定时器阶段队列中加入回调;当遇到setImmediate
时,在检查阶段队列中加入回调,事件循环开始工作。
那么,事件循环从哪一个阶段开始呢?有人说Poll
阶段,如果是真的,事件循环发现poll阶段队列为空,而check
阶段队列不为空,那么就应该执行console.log('world')
,然后事件循环到下一次迭代,到达timer
阶段,就执行console.log('hello')
,总之输出应该总是:
world
hello
其实并不总是这样。
那么,如何计算呢?
要解决这个问题,我必须阅读nodejs
的源代码?阅读相当困难的cpp代码?哦不,感觉真的很疯狂。
任何答案将不胜感激!
1条答案
按热度按时间ccgok5k51#
setImmediate
是non-standard,在V8中没有实现,所以这不是V8的问题。https://nodejs.dev/en/learn/understanding-setimmediate/表示:
延迟为0 ms的
setTimeout()
回调与setImmediate()
非常相似。执行顺序取决于各种因素,但它们都将在事件循环的下一次迭代中运行。节点文档对setImmediate说:
当对
setImmediate()
进行多次调用时,回调函数将按照创建顺序排队等待执行。而对于设置超时:
Node.js不保证回调触发的确切时间,也不保证它们的顺序。
所有这些听起来都没有一个简单的答案,你的代码可能不应该依赖于一个特定的顺序,这意味着你真的不需要关心是否能够预测顺序:-)