イベントループとは何ですか?実際に存在する物体ではなく、さまざまな段階の変化を表す概念です。生まれて、老いて、死んで、リングを形成するというライフサイクルに似ています。ある段階から次の段階にジャンプするプロセスです。
. nodejsブラウザのイベントループは
nodejsでは、イベントループはステージングされます: 興味のある3つの主なフェーズは次のとおりです: タイマーポールチェック。
各ステージはそれ自身のタスクキューを持っています。
タイマーはsetTimeoutとsetIntervalを保持しています。
ポーリング・ステージは、例えば1秒後にタイマーでf1が実行された場合、ポーリング・ステージでは、その後にタスクがなければ、時間が来るまでポーリングで停止し続け、タイマーに移動してコールバックを実行します。
チェック段階でsetImmediateを保存
もう一つ質問ですが、イベントループとJSコードの実行はどちらが先に始まるのでしょうか?ほとんどの場合、すべての準備が整ったら、JSコードが実行を開始し、eventloopはpollステージにとどまって待機するはずです。しかし、eventloopがタイマステージに入る前に、JSの実行開始を待って、非常にゆっくりと開くこともあり得ます。そのため、setTimeoutとsetImmediateの順序に問題が生じます。
setTimeout(() => {
console.log('setTimeout'); //f1
}, 0);
setImmediate(() => {
console.log('setImmediate'); //f2
});
nodeで実行すると、f1とf2のどちらが先に出力されますか?どちらかであることがわかりました。通常はf2が最初に表示され、次にf1が表示されるはずですが、実行するとf1が最初に表示され、次にf2が表示されることがあります。
timersステージにはタスクがないので、pollステージにジャンプして待機します。この時点で、JSコードが実行され、setTimeoutに遭遇してf1をtimerに入れ、setImmediateに遭遇してf2をcheckに入れます。で、f1が実行されます。
特殊なケース:eventloopがゆっくり開き、JSコードが先に実行されます。setTimeoutに遭遇したとき、f1をtimerに入れ、setImmediateに遭遇したとき、f2をcheckに入れました。このとき、eventloopがオープンされ、timerに入り、f1がすぐに実行されることがわかったので、そのまま実行しました。次にpollにジャンプして、実行されるタスクのcheckを見て、待たずにf2の実行のcheckに行きます。
つまり、setImmediateにあるものが必ず最初に実行されるというわけではありません。
f2を先に実行させるには?setTimeoutを使ってそれらをラップし、実行時間を全体として押し戻し、イベントループの開始準備ができたら、f1,f2を入れるようにします。
setTimeout(()=>{
setTimeout(() => {
console.log('setTimeout'); //f1
}, 0);
setImmediate(() => {
console.log('setImmediate'); //f2
});
},1000)
eventloopはpollの段階で準備をして待機している必要があり、check中のタスクを見つけると、まずf2を実行し、それからタイマに戻ってf1を実行します。そのため、setImmediateは通常setTimeoutの前に実行されます。両者は異なるフェーズにあるからです。
process.nextTick()という非同期APIもありますが、どのような順序ですか? process.nextTick()は特別な非同期APIで、Event Loopのどのフェーズにも属しません。実際、NodeがこのAPIに遭遇すると、Event Loopは全く続行されず、process.nextTick()を実行するために直ちに停止し、この実行後にEvent Loopを継続します。
setTimeout(()=>{
setTimeout(() => {
console.log('setTimeout'); //f1
}, 0);
setImmediate(() => {
console.log('setImmediate'); //f2
});
process.nextTick(() => {
console.log('nextTick 1'); //f3
});
},1000)
JSコードの実行では、setTimeoutに遭遇するとf1をタイマーに入れ、setImmediateに遭遇するとf2をチェックに入れます。nextTickに遭遇すると、カレントステージで実行されますが、まだポーリングステージなので、まずf3を実行し、次にチェックステージに入ってf2を実行し、タイマーに戻ってf1を実行します。
nextTickは常にpollステージで実行されるわけではなく、どのステージにいても実行されます。
setTimeout(()=>{
setTimeout(() => {
console.log('setTimeout'); //f1
process.nextTick(() => {
console.log('nextTick 2'); //f4
});
}, 0);
setImmediate(() => {
console.log('setImmediate'); //f2
});
process.nextTick(() => {
console.log('nextTick 1'); //f3
});
},1000)
f4は常にf1の後に続き、タイマーのステージで実行されます。簡単に言うと、nextTickは現在のステージの終了時に実行される次のステージにジャンプします。これは時間の中間転送ポイントにあります。
. ブラウザのイベントループ
ブラウザでは、イベントループはマクロタスクとマイクロタスクの2つのフェーズしかありません。
これはsetTimeout,Promise,async,awaitの順番に関係しています。





