我对nextTick和setImmediate之间的区别感到非常困惑。我已经在互联网上阅读了有关它们的所有文档,但我仍然不明白它们是如何工作的。
例子:
function log(n) { console.log(n); }
setImmediate
setImmediate(function() { setImmediate(function() { log(1); setImmediate(function() { log(2); }); setImmediate(function() { log(3); }); }); setImmediate(function() { log(4); setImmediate(function() { log(5); }); setImmediate(function() { log(6); }); }); }); //1 2 3 4 5 6
nextTick
process.nextTick(function() { process.nextTick(function() { log(1); process.nextTick(function() { log(2); }); process.nextTick(function() { log(3); }); }); process.nextTick(function() { log(4); process.nextTick(function() { log(5); }); process.nextTick(function() { log(6); }); }); }); //1 4 2 3 5 6
为什么会有这些结果?请以视觉或非常容易理解的方式进行说明。甚至节点核心开发人员也不同意人们应该如何理解nextTick和setImmediate。
资料来源:
考虑以下两个示例:
setImmediate(function A() { setImmediate(function B() { log(1); setImmediate(function D() { log(2); }); setImmediate(function E() { log(3); }); }); setImmediate(function C() { log(4); setImmediate(function F() { log(5); }); setImmediate(function G() { log(6); }); }); }); setTimeout(function timeout() { console.log('TIMEOUT FIRED'); }, 0) // 'TIMEOUT FIRED' 1 4 2 3 5 6 // OR // 1 'TIMEOUT FIRED' 4 2 3 5 6
process.nextTick(function A() { process.nextTick(function B() { log(1); process.nextTick(function D() { log(2); }); process.nextTick(function E() { log(3); }); }); process.nextTick(function C() { log(4); process.nextTick(function F() { log(5); }); process.nextTick(function G() { log(6); }); }); }); setTimeout(function timeout() { console.log('TIMEOUT FIRED'); }, 0) // 1 4 2 3 5 6 'TIMEOUT FIRED'
setImmediate回调从事件循环中触发,每次迭代按排队的顺序进行一次。因此,在事件循环的第一次迭代中,将触发回调A。然后,在事件循环的第二次迭代中,将触发回调B,然后在事件循环的第三次迭代中,将触发回调C,以此类推。这样可以防止事件循环被阻塞,并允许其他I / O或计时器回调在平均时间中调用(与0ms超时的情况相同,它在第1次或第2次循环迭代中触发)。
但是,总是在执行完当前代码之后并返回事件循环之前立即触发nextTick回调。在nextTick示例中,在返回事件循环之前,我们最终执行了所有nextTick回调。由于将从事件循环中调用setTimeout的回调,因此直到完成每个nextTick回调后,才会输出文本“ TIMEOUT FIRED”。