2013-05-20 47 views
10

私はa JavaScript libraryに取り組んでいます。特に、非同期的に反復できるシーケンスのmap/reduce関数を提供しています。非同期の反復処理にはprocess.nextTickまたはsetImmediateを使用する必要がありますか?

helpful soul on GitHubは、Node.jsに対して、できるだけ早く非同期の反復を行うには、process.nextTickを使用することを推奨します。 (ライブラリは現在、すべての環境でsetTimeoutを使用していますが、私は理解できませんが、それは最適ではありません)。ノードに関してはとても経験がないので、この方法の仕組みを読んでいました。良い選択かどうか。

the answer to another question on SOによると、おそらく明らかに私に悪いようです保留中のI/OイベントのジャンプnextTickこの場合のsetImmediateを使用する方が理にかなっているようです。

これはthe official Node v0.10.0 announcmentに、いくつかの発言によって裏付けられているように見える:v0.10で

は、nextTickハンドラは、右のJavaScriptにC++ から各呼び出しの後に実行されます。つまり、JavaScriptコードが process.nextTickを呼び出した場合、コードが で完了するとコールバックが発生しますが、の前には、がイベントループに戻ります。

私は正しく、シーケンスを非同期的に反復するには、setImmediateで行う必要がありますか?またはnextTickはここでより良い選択ですか? (いずれの場合も、明確な説明がはるかに高く評価されるだろう、なぜ。)

+0

「非同期の繰り返し」が必要なのはなぜですか。 –

+0

あなたは、アイテムごとに高価な処理を適用する必要があるデータ項目のリストが長いとします。 'nextTick' /' setImmediate'を使用することにより、他のコードを各処理ステップの間に実行させることができる。 HTTP要求への応答、または例えばGUIとのユーザーの対話。 – flow

答えて

10

いくつかの注意事項:

は、私が最初setImmediateがprocess.nextTickより遅い延長ものに深刻なベンチマークにしてください。それが(はるかに)遅くない場合、私はsetImmediateのために行くだろうので、それはイベントループを飢えさせないので、すぐに行きます。

ノード0.10には、何回も再帰的にnextTickを呼び出すことができるハード制限(1000、node.js docsを参照)がありますので、どのような場合でも起こらないようにする必要があります。反復の前に戦略を選択するか、繰り返し中に戦略を変更できる(現在の反復回数を確認しながら)必要があります。

パフォーマンス上の理由からprocess.nextTickを選択した場合は、process.nextTickを何回実行するかを設定可能なハード制限を設定し、それ以外の場合はsetImmediateに切り替えます。私はnodejsで重大な作業負荷を経験していませんが、あなたのライブラリがI/Oが不安定になっても人々がそれを気に入らないと思います。

setImmediateは確かに最も安全です。ブラウザについては

: 私はあなたのライブラリーを研究していないが、あなたが実際にsetTimeoutから来ているので、あなたは新しいwindow.postMessageを経由して遅延技術の品種やものではありませんについての学習に役立っすることができます。 next-tickという素敵な小さなライブラリがありますが(ノードnext-tickとは意味が異なります)、cross-browser shim for setImmediateがあります。これは、1)setImmediate仕様(スケジュールされたタスクをキャンセルする機能を含む)と、 2)ブラウザの互換性がはるかに広い。

チェックアウトasync sorting demo setImmediate(shim)とsetTimeoutを比較します。

+1

'nextTick'が何らかの形で' setImmediate'よりかなり高速だったとしても、 'setImmediate'をもう一度呼び出す前にもっと多くの作業を実行する方が良いと思います。とにかくすべてをブロックすることになったら、結局のところコードの実行をマーシャリングする必要はありません。 – Hristo

+1

@HristoDachev:良い点。しかし、彼の疑問が残っているので、なぜ「非同期的に反復する」必要があるのか​​正確には分かりません。作業を同期して実行されるバッチに分割すると、非同期性の一部が失われます。バッチ操作のための非同期インターフェースが必要なだけであれば、作業量全体のための単一の「setImmediate」で十分であり、速度の違いは無関係です。私は尋ねます。 –

+0

いいえ、上記の私のコメントを参照してください。 – flow

関連する問題