以前イベント周回ブログをいくつか読んだことがありましたが、しばらく読んでいなかったのですっかり忘れていたことに気づき、まとめとしてブログを書くことにしました!
私たちの知る限り、ブラウザの js はシングルスレッドです。つまり、同時に実行されるコード セグメントは最大でも 1 つだけです。しかし、ブラウザは非同期リクエストを非常にうまく処理できるのに、なぜでしょうか?まずは画像を見てみましょう
上の画像から、js メインスレッドに実行スタックがあり、すべての js コードが実行スタック内で実行されることがわかります。コードの実行中に、非同期コード (setTimeout、ajax、promise.then、ユーザーのクリックなど) が発生すると、ブラウザーはこれらのコードをスレッド (ここではビハインドザと呼びます) に入れます。 -scenes thread) 待機しても、メイン スレッドの実行はブロックされません。バックグラウンド スレッドのコードの準備が整ったとき (たとえば、setTimeout 時間が経過し、ajax リクエストが完了したとき)、メイン スレッドはスタック内の残りのコードを実行し続けます。が応答されると、スレッドはそれを処理します。コールバック関数は実行を待機するタスクキューに配置されます。メインスレッドは、スタック内のすべてのコードの実行を終了すると、タスクキューをチェックして、実行すべきタスクがあるかどうかを確認し、実行すべきタスクがある場合、そのタスクは実行スタックに置かれます。実行。現在のタスクキューが空の場合、タスクが到着するまでループで待ち続けます。したがって、これはイベント ループと呼ばれます。
console.log(1) setTimeout(function() { //settimeout1 console.log(2) }, 0); const intervalId = setInterval(function() { //setinterval1 console.log(3) }, 0) setTimeout(function() { //settimeout2 console.log(10) new Promise(function(resolve) { //promise1 console.log(11) resolve() }) .then(function() { console.log(12) }) .then(function() { console.log(13) clearInterval(intervalId) }) }, 0); //promise2 Promise.resolve() .then(function() { console.log(7) }) .then(function() { console.log(8) }) console.log(9)
結果はどうなると思いますか?
ノード環境と Chrome コンソールで出力した結果は次のとおりです:
1 9 7 8 2 3 10 11 12 13
上記の例では、
settimeout2 を実行し、マクロタスクキューに参加します
2 番目のイベント ループ:
マクロタスク キューからチーム (settimeout1) を取得して実行すると、出力 2 マイクロタスク キューは空です。戻り、最初のステップに戻り、次のイベント ループに入ります。この時点で、マクロタスク キューは setinterval1、settimeout2
3 番目のイベント ループ:
マクロタスク キューからチームの先頭のタスク (setinterval1) を取得し、実行して 3 を出力し、新しく生成された setinterval1 をマクロタスク キューに追加します。マイクロタスク キューは空です。最初のステップに戻り、次のイベント ループに入ります。このとき、マクロタスク キューは次のとおりです: settimeout2, setinterval1
マイクロタスクキューから、キューの先頭にあるタスクを取り出し、空になるまで実行します。したがって、新しく追加された 2 つのマイクロタスク タスクが順番に実行され、出力 12 と 13 が実行され、setinterval1 はクリアされます。このとき、ブラウザはキューが空かどうかを常に確認して待機します。新しいタスクをキューに追加します。
理由: jsメインスレッドで最初に実行されているタスクはマクロタスクタスクであり、イベントループの処理に応じて、イベントループはメインスレッドのコードを実行した後にマクロタスクタスクを1つだけ実行するためです。 、マイクロタスクキューに移動し、チームのリーダーにタスクを実行してもらいます。
setTimeout(task,100) を実行した後、実際にはタスクが 100 ミリ秒後にマクロタスク キューに入ることが保証されるだけで、すぐに実行できるという意味ではないため、誰もがその理由を知っているはずです。 master スレッドが時間のかかる操作を実行しているか、現在マイクロタスクのキューに多くのタスクがある可能性があるため、これが setTimeout を批判している理由かもしれません。イベントループといくつかの参考文献 その他の素晴らしい記事
以上がjsイベントループの例を詳しく解説の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。