私たちが知っている、ノードは、それはまた、イベントループJSエンジンを有することを意味クロームV8エンジン、に基づいてイベントループメカニズムです。ノードは、サーバー側で実行されている。しかし、ブラウザ側は異なるがあります。例えば、よりsetImmediate、process.nextTickおよび非同期APIブラウザ以外。そして、イベントループ・メカニズムは確かに同じではありません。ここでは、ノードのイベントループが操作の一種である方法を見て。
ノードのイベントループ
1.ノードイベントループは、単にその(等nextTickQueue、microTaskQueue、など)いくつかのキューにスレッド(すなわちJSメインスレッド)によると見ることができます。メインスレッドキューから常時取得して実行するタスク、同様の一方(TRUE){}絶えず循環
メインイベントループ2.スレッド上に完了する
3.タスクの同期タスクの実行優先度と同期非同期タスクを含むイベントループは非同期タスクよりも大きい場合、そのタスクの同期は常に非同期タスクの前に実行されています。
図1にconsole.log( 'Iは、同期タスク、第一の出力よ' ) 2 process.nextTick(()=> { 3 はconsole.log( 'I非同期タスク、第3の出力' ) 4 }) 。5のsetTimeout( ()=> { 6 はconsole.log( 'I非同期タスク、第4の出力' ) 。7 }) 。8 setImmediate(()=> { 9 はconsole.log( 'I非同期タスク、第五の出力' ) 10 }) 。11はconsole.log( 'I同期タスク、第二出力よ' ) 12 // 出力 13 // I同期タスク、第一の出力 14 // I同期タスク、第二の出力 15 //私のタスクが非同期であり、そして第3の出力 16は // 私は非同期タスクを午前、第4の出力 17 // 私は非同期タスクを午前、第五出力
時間のために、ここで、理解を容易にするために4.私たちはしばしば言う非同期タスクの中に置かれているマイクロタスク(マイクロタスク)とマクロタスク(マクロタスク)。マイクロタスクが含まnextTickQueueとmicroTaskQueue(理解を容易にするために、後者のマイクロタスクが参照nextTickQueueとmicroTaskQueueの)、マクロタスクが含まのsetTimeout / のsetInterval / setImmediate / IOコールバック/コールバックHTTPようにとします。どのマイクロタスクは、現在のサイクルで実行され、マクロタスクは、タスクのみの内側にマイクロタスクと内部行っ現在のサイクル同期タスクが完了した後に行われます。そして、マクロタスクの実装では、優先順位は、直接次のマクロタスクを実行しない場合は、その後、次のサイクルに進む前に、完全に実行するタスクがないマイクロタスクを確認し、内部の同期タスクを実行します。このような円形の無限ループは、サービス終了を知っています。これはイベントループです。
現在のサイクル5.実行JSスレッドの順番はこれです:同期タスク> nextTickQueue> microTaskQueueは、つまり、チェックを実行した後に同期タスク、タスクの同期を実行するためにnextTickQueue何のタスクキュー、任意の実行nextTickQueue、まではありませんnextTickQueue内のタスクが実行された後、次のサイクルが継続されない場合は、その後、何の判断microTaskQueueタスクキュー、任意の実行はありません。microTaskQueueが空になるまでmicroTaskQueueタスクを実行するとき、彼らはPromise.then()とprocess.nextを()表示された場合、実行microTaskQueueまでオフに保持されることに注意してください、そしてnextTickQueueを判断します。
1にconsole.log( '1' ) 2 process.nextTick(()=> { 3 はconsole.log( 'ダニ1' ) 4 process.nextTick(()=> { 5 はconsole.log( 'ダニ2' ) 6 }) 7 }) 8 9 Promise.resolve()。次に、(()=> { 10 はconsole.log( 'Promise.then 1' ) 11 process.nextTick(()=> { 12 はconsole.log( 'ダニ3 ' ) 13 }) 14 Promise.resolve()。次に、(()=> { 15 console.logは( 'Promise.then 2' ) 16 }) 17 }) 18 // 输出结果: 19 // 1 20 // ティック1 21 // 2目盛り 22 // Promise.then 1 23 // Promise.thenを2 24 // ダニ3
6.マクロタスクを持っているかどうかを判断するためにキューに移動します現在のマクロタスクの実行後に終了したら、どんなアウトが続きます。
7.イベントループアーキテクチャ
8.私たちは、図から見ることができ、イベントループは、図の順序に従って実行された6つのステージに分割されます。各ステージは、各実行ステージは、FIFO原理に従って、タスク内のステージを横断する独自のキュー、対応するタスクのストレージを有するステージがタスクの実行が完了した後に実施される場合にのみ適用されています舞台。microTaskQueueとnextTickQueue各タスクの各段階を行う首都圏の時に行われることに留意すべきです。これは、タイマーがキュー場合は3つのタスク、タスクを実行する各microTaskQueue、任意の最初の実行でnextTickQueueタスクがあるかどうかを判断し、次に実行した後、次のタスクを実行することになりますが存在することを意味します。2つの無限のキューが実行された場合は、フォローアップするために、前回のシステムクラッシュを遮断する作業をリードします。だから私は、マイクロタスクが、マクロタスクに添付されるように、各マクロタスクは、マイクロタスクを実行する現在のマクロタスク子会社は、次のマクロタスク実行された場合にのみ、自分のマイクロタスクが含まれていてもよい理解しています。
9.次は簡単ではどのような段階に分けてそれぞれ言います:
1)タイマフェーズ:フェーズタイマ、主のsetTimeout /たsetIntervalコールバック関数を扱います。この段階に入るとき、メインスレッドは、そうでなければ次の段階に進み、それが実行され、タイマーの要件を満たすために、現在の時間、すなわち遅延タイマに設定されているかどうか、であるかどうかを決定します。
2)保留中のI / Oコールバックステージ:.コールバック相IO、IO処理コールバック関数。
3)アイドル、特に明確ではない、相:.ノードの内部動作を準備
4)ポーリング段階:ポーリング、IOはまだ戻っていないイベントを待ちます
setImmediateコールバックの実装:5)相を確認してください。
6)を閉じるコールバック:.コールバック要求をオフに行わ、例えばsocket.on( 'クローズ'、()=> {})
これはおそらく、6つの段階によって説明され、我々はときのsetTimeout遅延がゼロ(理想的な状態)であることを知ることができ、実際には、setImmediateの実装では優先事項であるが、実際には、これは保証されていない場合、 setTimeoutわずかな遅延があるため、コールバック関数につながるキュータイマ段階にまだなかったので、setImmediateはsetTimeoutメソッドの実装に優先順位を与えます。これは、いくつかの他の制御不能な要因とマシンの性能に依存します。しかし、次のコードは、setImmediateのsetTimeoutよりも優先し、その理由を確保することができますか?setImmediateは第5段階にあり、IOコールバックは、第二段階であるため、のsetTimeoutは、第一段階です。IOコールバックが実行されたとき、第一相(のsetTimeout)が5段目(setImmediate)の順序に従って、レースを終えた最初の実行されます。
1 fs.readFile(」./ test1.js'、 'UTF-8'、()=> { 2 のsetTimeout(()=> { 3 はconsole.log( 'IOコールバックでのsetTimeout' ) 4 }) 5 setImmediate( ()=> { 6 はconsole.log( 'IOコールバックでsetImmediate' ) 7 process.nextTick(()=> { 8 はconsole.log( 'IO-setImmediateコールバックの処理' ) 9 }) 10 }) 11の プロセス。 nextTick(()=> { 12 はconsole.log( 'IOコールバックの処理') 13 }) 14 はconsole.log( 'IOコールバックに同期' ) 15 }) 16 // 输出结果: 17 // IOコールバックのSYNC 18 // プロセスIOコールバックで 19 // IOコールバックでsetImmediate 20 // プロセスでIO-setImmediateコールバック 21 // IOコールバックでのsetTimeout
setTimeoutとsetImmediateの比較:のsetTimeoutは、現在のタスクが実行可能である計算し、それを実行することができます。setImmediate計算する必要はありませんが、直接キューに置かれ、その相対的なパフォーマンスsetImmediateが良いのsetTimeoutとなり、何も