created: 2020-04-19T04:35:05.000Z

nodejsのEvent Loopについておおまかなメモ

nodejsのイベントループは次の6個のフェーズからなる

  • timers
  • pending callbacks
  • idle, prepare
  • poll
  • check
  • close callbacks

この6個のフェーズの1周はラウンドと呼ばれる

それぞれのフェーズはそれぞれのキュー(実行すべき処理のリスト)をもっている

また、それぞれフェーズごとのキューとは別に2つキューがある この2つのキューは各フェーズとフェーズの合間に消化される

  • nextTickQueue
    • process.nextTick で登録されたコールバックがはいるキュー
  • microTaskQueue
    • Promise オブジェクトに登録されたコールバックはこのキューに入る

それぞれのフェーズ

どういった経路で登録されたコールバックかによって実行されるフェーズが違う

timers

setTimeout, setInterval で設定されたイベントが処理される

pending callbacks

IOエラーに伴うコールバックが処理される

たとえば、ECONNREFUSED が返ってきてる場合などはこのフェーズで処理される

idle, prepare

内部的な処理を行うフェーズで普段ユーザは意識しない

poll

このフェーズはカーネルに依頼した処理のポーリングなど

  • IOなどのポーリング (ブロックしてポーリングする)
  • ポーリングキューの結果実行できるようになったイベントの処理

ポーリングは必ずしも処理が完了するまで待つのではなく、そのときそのときでリーズナブルな待ち時間を計算してその分だけ待つことになっている (その待ち時間で結果が返ってこなかったら次のラウンドに持ち越す)

なお、IOエラーが返ってきた場合はこのフェーズでは処理されず、次のラウンドのpending callbacksまで処理が持ち越される

check

setImmediate で登録された処理が実行される

close callbacks

close イベントを処理する

  • eg: readable.on('close', () => {})

close はたとえば socket.destroy() などでも発生する

参考

イベントループにはもっと知っておくべきことや詳細な実行順序などがある
(たとえば nextTickQueue, microTaskQueue では nextTickQueue のほうが先に処理されることなど)