2011-11-13 30 views
54

私はprocess.nextTickがいくつかの場所で使われているのを見てきました。Node.jsのprocess.nextTickの適切な使用例は何ですか?

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

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

私の質問は、サーバー側のJavaScriptでこれをどうすればいいですか?私はこの種の微調整されたパフォーマンス/フロー制御が必要なバットからすぐには見当たらない。ちょうど正しい方向にポイントを探しています。

+2

Howtonodeには[process.nextTick()の理解に関する優れた記事があります](http://howtonode.org/understanding-process-next-tick) –

答えて

67

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); 
} 
+0

ありがとうございました。 –

+1

また、setTimeoutが遅すぎます。 – Parris

+3

"このキューのすべてのコールバックは、イベントループの次のティックの始めに実行されます。私はこれがもう完全に正確ではないと思う。私が理解しているように、キューは現在のチックの終わりに処理されます。 "v0.10では、C++からJavaScriptへの各呼び出しの直後にnextTickハンドラが実行されます。つまり、JavaScriptコードがprocess.nextTickを呼び出すと、コードが完了するとすぐにコールバックが実行されますが、イベントループに。 - [ノード0.10.0発表](http://blog.nodejs.org/2013/03/11/node-v0-10-0-stable/)から –

15

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

コールスタックをオーバーフローさせることなく、関数を再帰的に実行するために使用できる場合は、それ以外のものがあります。

編集:現在、node's setImmediate functionというスケジューリングで、保留中のI/Oイベント(新しいWebリクエストの処理など)の後に実行される機能があります。私はuse case in the answer of this questionを説明しました。

関連する問題