为 setTimeout 和 setImmediate 和 setTimeout 获得不同的结果
Getting different results for setTimeout & setImmediate inside setTimeout
setImmediate(function () {
console.log('setImmediate')
});
setTimeout(function () {
console.log('setTimeout')
}, 0);
产出
setTimeout
setImmediate
但是,setTimeout 中的这两个函数输出不同的结果。
setTimeout(function () {
setImmediate(function () {
console.log('setImmediate')
});
setTimeout(function () {
console.log('setTimeout')
}, 0);
}, 0);
输出:
setImmediate
setTimeout
我们知道事件循环看起来像这样-
timers -> IO -> poll -> check ->close -> timers -> ...
计时器:来自 setInterval 或 setTimeout 的回调
IO 回调:来自 I/O 事件的回调
Idle:在 IO 和 Poll 阶段之间由 Node 内部使用
投票:检索新的 I/O 事件
检查:来自 setImmediate 的回调在这里执行
close:像sockets一样处理关闭的连接
在第一个例子中-
我们可以看到 setTimeout 在 setImmediate 之前执行,因为 timer queue 位于 check Queue.
之前
然而在第二种情况下-
当 setTimeout 被执行时,它会触发另一个 setTimeout 和一个 setImmediate,因为 Check queue 被放置在 timer queue 之后,同一循环的检查队列执行 setImmediate,但 嵌套的 setTimeout 被安排在下一个周期 。
这就是为什么下面的代码也可以用于 运行 定期
let timerId = setTimeout(function tick() {
alert('tick');
timerId = setTimeout(tick, 2000); // (*)
}, 2000);
它安排下一次调用,就在第一次调用结束时,这基本上为下一个循环注册了 setTimeout 的调用。
setImmediate(function () {
console.log('setImmediate')
});
setTimeout(function () {
console.log('setTimeout')
}, 0);
产出
setTimeout
setImmediate
但是,setTimeout 中的这两个函数输出不同的结果。
setTimeout(function () {
setImmediate(function () {
console.log('setImmediate')
});
setTimeout(function () {
console.log('setTimeout')
}, 0);
}, 0);
输出:
setImmediate
setTimeout
我们知道事件循环看起来像这样-
timers -> IO -> poll -> check ->close -> timers -> ...
计时器:来自 setInterval 或 setTimeout 的回调 IO 回调:来自 I/O 事件的回调 Idle:在 IO 和 Poll 阶段之间由 Node 内部使用 投票:检索新的 I/O 事件 检查:来自 setImmediate 的回调在这里执行 close:像sockets一样处理关闭的连接
在第一个例子中-
我们可以看到 setTimeout 在 setImmediate 之前执行,因为 timer queue 位于 check Queue.
之前然而在第二种情况下-
当 setTimeout 被执行时,它会触发另一个 setTimeout 和一个 setImmediate,因为 Check queue 被放置在 timer queue 之后,同一循环的检查队列执行 setImmediate,但 嵌套的 setTimeout 被安排在下一个周期 。
这就是为什么下面的代码也可以用于 运行 定期
let timerId = setTimeout(function tick() {
alert('tick');
timerId = setTimeout(tick, 2000); // (*)
}, 2000);
它安排下一次调用,就在第一次调用结束时,这基本上为下一个循环注册了 setTimeout 的调用。