node.js - nextTick vs setImmediate,直观解释

标签 node.js

我对 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

为什么会出现这些结果?请用视觉或非常容易理解的解释来解释。即使是 Node 核心开发人员也不同意人们应该如何理解 nextTick 和 setImmediate。

来源:

最佳答案

考虑以下两个例子:

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

nextTick

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”。

关于node.js - nextTick vs setImmediate,直观解释,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17502948/

相关文章:

node.js - 消息因涉嫌垃圾邮件而被拒绝 Nodejs、Yandex、Firebase 函数

javascript - 如何在一次查询中获取多个计数?

javascript - 如何将事件处理程序附加到 native Node.js 模块中的进程导出?

node.js - Express 和 Node.js 超时

node.js - $unset 为空。您必须指定一个像这样的字段 : {$unset: {<field>: . ..}}

javascript - NodeJS module.exports 子模块

node.js - 运行 parallelshell Nodejs 脚本时出现问题

node.js - 在 Angular 2 中创建构建时 JavaScript 堆内存不足错误

javascript - 如何合并 MongoDB 查找查询的输出?

javascript - 使用 Node Js 重定向无法正常工作