Node.js 中 process.nextTick 的正确用例是啥?

Posted

技术标签:

【中文标题】Node.js 中 process.nextTick 的正确用例是啥?【英文标题】:What are the proper use cases for process.nextTick in Node.js?Node.js 中 process.nextTick 的正确用例是什么? 【发布时间】:2011-12-28 02:44:29 【问题描述】:

我在一些地方看到process.nextTick 被使用,但不能完全确定它的用途。

https://github.com/andrewvc/node-paperboy/blob/master/lib/paperboy.js#L24 https://github.com/substack/node-browserify/blob/master/index.js#L95

process.nextTick 在 Node.js 中的主要/正确用例是什么?文档基本上说这是一种更优化的 setTimeout 方式,但这并没有太大帮助。

我曾经做过很多动作脚本,所以“等到下一帧”来执行代码的想法在某种程度上是有意义的 - 如果您正在运行动画,您可以让它更新每一帧而不是每毫秒例如。当您想要协调设置一堆变量时,这也很有意义 - 您在第 1 帧中更改变量,并在第 2 帧中应用更改。Flex 在其组件生命周期中实现了类似的东西。

我的问题是,我应该在服务器端 javascript 中使用它做什么?我没有看到任何需要这种微调性能/流量控制的地方。只是在正确的方向上寻找一个点。

【问题讨论】:

Howtonode 有一个excellent article on understanding process.nextTick() 【参考方案1】:

process.nextTick 将回调放入队列。此队列中的每个回调都将在事件循环的下一个滴答开始时执行。它基本上被用作清除调用堆栈的一种方式。当文档说它就像setTimeout 时,它的意思是说它就像在浏览器中使用setTimeout(function() ... , 1)。它具有相同的用例。

一个示例用例是,您为某个需要绑定事件的对象创建一个构造函数。但是,您不能立即开始发出事件,因为实例化它的代码还没有时间绑定到事件。您的构造函数调用在调用堆栈中位于它们之上,如果您继续执行同步操作,它将保持这种状态。在这种情况下,您可以使用process.nextTick,然后再继续您将要做的任何事情。它保证使用您的构造函数的人将有足够的时间来绑定事件。

例子:

var MyConstructor = function() 
  ...
  process.nextTick(function() 
    self._continue();
  );
;

MyConstructor.prototype.__proto__ = EventEmitter.prototype;

MyConstructor.prototype._continue = function() 
  // without the process.nextTick
  // these events would be emitted immediately
  // with no listeners. they would be lost.
  this.emit('data', 'hello');
  this.emit('data', 'world');
  this.emit('end');
;

使用此构造函数的示例中间件

function(req, res, next) 
  var c = new MyConstructor(...);
  c.on('data', function(data) 
    console.log(data);
  );
  c.on('end', next);

【讨论】:

另外,setTimeout 太慢了。 "此队列中的每个回调都将在事件循环的下一个滴答开始时执行。"我认为这不再完全准确。据我了解,队列是在当前滴答结束时处理的。 “在 v0.10 中,nextTick 处理程序在每次从 C++ 调用 JavaScript 后立即运行。这意味着,如果您的 JavaScript 代码调用 process.nextTick,则回调将在代码运行完成后立即触发,但在返回之前到事件循环。” - 来自Node 0.10.0 announcement【参考方案2】:

它只是在当前操作结束时在下一次 I/O 回调之前运行您的函数。 Per documentation 您可以在调用者同步代码执行后使用它运行您的代码,如果您可以使用它为您的 API/库用户提供注册需要尽快发出的事件处理程序的机会,则可能是这样。另一个用例是确保您始终以异步方式调用回调以在不同情况下具有一致的行为。

在过去 process.nextTick 将被用于为 I/O 事件提供执行机会,但这不再是行为,而是为该行为创建了 setImmediate。我解释了一个use case in the answer of this question。

【讨论】:

"它只是将你的函数放在事件循环的末尾。" - 不,不是,nextTick 在当前操作结束时执行,在事件循环继续之前。 @Marko 谢谢,抱歉,这是旧行为,我懒得更新它。现已更新,感谢通知。

以上是关于Node.js 中 process.nextTick 的正确用例是啥?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 node.js 中找到前 10 个最慢的函数?分析 node.js

Node.js:如何将 Node.js 嵌入 HTML?

Node.js 模块

[Node.js]Buffer

PHP 与 Node.js - 在 Node.js 中使用 Jade 的 HTML 渲染速度会变慢吗?

node.js 项目中的 index.js 用于啥?