Nodeのイベントループ

Nodeのイベントループ

Node の基盤となる言語は libuv で、v8 エンジンを使用して js スクリプトを解析します。
libuv はインターフェイス API を呼び出し、さまざまなタスクをさまざまなスレッドに渡して処理し、処理結果を v8 エンジンに渡し、v8 エンジンは処理結果をユーザーに送信します。
Node でのタスクの実行順序

  1. timers タイマー、並べたsetTimeoutとsetIntervalのコールバック関数を実行
  2. 保留中のコールバック: 次のループ反復まで実行が遅延される I/O コールバック
  3. アイドル、準備: システムによって内部的にのみ使用されます
  4. poll: 新しい I/O イベントを取得し、I/O 関連のコールバックを実行します。
  5. check: setImmedate() コールバック関数を実行する
  6. クローズド コールバック関数クローズ コールバック: たとえば、socket.on('close', ()=>{})

Node はオペレーティング システムを処理するため、
ブラウザのマクロ タスクがキューであるかどうかに関係なく、アイドル/準備/保留中のコールバックは Node の 6 つのマクロ タスク キューと見なすことができ、各キューは実行時に現在のキューをクリアします。 . キュー内のコールバック タスクは次のキューに移動します.
マイクロタスク: process.nextTick および Promise マイクロタスクを考慮すると、各キューが実行される前に、nextTick キューがクリアされてから Promise が実行されます.
process.nextTick > setImmediate > microtask
setImmediate と setTimeout(0) の実行順序直接実行すると、setTimeout(0) が最初に実行され、次に setImmediate が実行
れることがわかります。
オペレーティング システムの速度。setTimeout のプログラムは setImmediate よりも明らかに複雑で、タイマーを作成する必要があるため、setTimeout の実行イベントは setImmediate よりも長くなります。

console.log('start');
let timer1 = setTimeout(() => {
    
    
    console.log(`settimeout 0`)
    process.nextTick(() => {
    
    
        console.log('settimeout process nextTick');
    })
    clearTimeout(timer1);
}, 0);
let timer2 = setTimeout(() => {
    
    
    console.log(`settimeout 300`)
    clearTimeout(timer2);
}, 300);
let interval = setInterval(() => {
    
    
    console.log(`setInterval`)
    clearInterval(interval);
}, 0);


process.nextTick(() => {
    
    
    console.log('process nextTick');
})
const fs = require('fs')
fs.readFile('./test.js', () => {
    
    
    console.log('poll');
    setImmediate(() => {
    
    
        console.log(`poll setImmediate`)
    });
})
setImmediate(() => {
    
    
    console.log(`setImmediate`);
});
new Promise(resolve => {
    
    
    console.log('promise start');
    resolve();
    console.log('promise end');
}).then(() =>{
    
    
    console.log('promise result');
})
console.log('end');
start
promise start
promise end
end
process nextTick
promise result
settimeout 0
setInterval
settimeout process nextTick
setImmediate
poll
poll setImmediate
settimeout 300

  1. 印刷開始
  2. timer1 はタイマー キューに参加します
  3. timer2 はタイマー キューに参加します
  4. インターバル ジョイン タイマー キュー
  5. すぐにチェック キューに参加します
  6. process.nextTick がマイクロタスク キューに参加します
  7. fs は I/O キューに参加します
  8. Promise の実行、Promise の開始、Promise の終了の出力 非同期マイクロタスク キューへのコールバックの追加
  9. 印刷スクリプト終了
  10. マイクロタスク キューを空にし始める
  11. promise.nextTick コールバックをクリアする
  12. promise コールバック キューをクリアする
  13. マクロタスク キューを空にし始める
  14. タイマーをクリアし、setTimeout(0) を実行し、マイクロタスク キューに process.nextTick を追加します。
  15. setTimeout(300) 時間が経過していないため、引き続きタイマーに配置され、実行されません
  16. setintervalexecution
  17. タイマー キューが空になりました。マイクロタスクを探します。ある場合は、process.nextTick を実行します。
  18. ポーリング キューを空にすることを開始します。この時点では、タスクを実行する時間ではありません。ポーリングは待機し、他のキューにタスクがあるかどうかを確認します。
  19. setImmediate コールバックが存在するため、ポーリングは待機します。まず、setImmediate の実行が完了するまで待機します。
  20. ポーリング キュー タスクの実行時間切れ、タスクのクリア、ポーリングの印刷、チェック キューへの setImmediate の追加
  21. チェック キューをクリアしてポーリングを印刷する setImmediate
  22. 1 サイクルが終了し、次のサイクルを開始する
  23. タイマー キューを空にし始める
  24. この時点で setTimeout(300) だけが残っています

おすすめ

転載: blog.csdn.net/qq_41028148/article/details/125263071