web-dev-qa-db-ja.com

Node.jsのprocess.nextTickの適切な使用例は何ですか?

私は process.nextTick がいくつかの場所で使用されているのを見てきましたが、それが何のために使用されているのかまったくわかりません。

Node.jsのprocess.nextTickの主な/適切な使用例は何ですか?ドキュメントは基本的にそれがsetTimeoutを行うためのより最適化された方法であると述べていますが、それはあまり役に立ちません。

私は多くのActionScriptを使用していたため、コードを実行するために「次のフレームまで待機する」という考えは、ある程度の意味で理にかなっています。たとえば、アニメーションを実行している場合は、ミリ秒ごとではなくフレームごとに更新することができます。一連の変数の設定を調整したい場合にも意味があります。フレーム1で変数を変更し、フレーム2で変更を適用します。Flexは、コンポーネントのライフサイクルでこのようなものを実装しました。

私の質問は、サーバー側のJavaScriptでこれを何に使用すればよいですか?この種の微調整されたパフォーマンス/フロー制御を必要とするような場所は、すぐには見つかりません。正しい方向のポイントを探すだけです。

58
Lance Pollard

_process.nextTick_は、コールバックをキューに入れます。このキュー内のすべてのコールバックは、イベントループの次のティックの最初に実行されます。これは基本的に、コールスタックをクリアする方法として使用されます。ドキュメントでsetTimeoutのように記載されている場合は、ブラウザでsetTimeout(function() { ... }, 1)を使用しているように記載されています。同じ使用例があります。

使用例の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);
}
_
71
chjj

それは単にあなたの関数をイベントループの終わりに置くだけです。通常、重い同期処理を実行している場合は、プロセスが他のイベントをブロックしないように、コードのチャンクごとにprocess.nextTickを使用することをお勧めします。これを行うと、proess.nextTickに到達して関数が終了すると、httpリクエストなどの他のイベントが処理され、process.nextTickコールバックに到達して実行されます。

それ以外に、呼び出しスタックがオーバーフローすることなく、関数を再帰的に実行できる場合は!

編集:現在、 ノードのsetImmediate関数 があり、スケジュールは、保留中のI/Oイベント(新しいWebリクエストの処理など)の後に実行される関数です。 この質問の答えのユースケース

16