イベント ループは、JavaScript コードの実行順序を維持する (メイン スレッドをブロックせずに非同期操作を処理する) ループです。
イベント ループに入る前に知っておくべきこと:
- コールスタック: ここで JavaScript がコードを実行します。これは後入れ先出し (LIFO) 構造に従います。関数が呼び出されると、新しい実行コンテキストが作成され、スタックにプッシュされます。機能が終了すると、外れます。
- MicroTasks キュー: queueMicroTask メソッド、Promise ハンドラー、await 専用の特別なキュー コールバックとMutationObserver (インターフェースは、DOM ツリーに加えられた変更を監視する機能を提供します)。
- MacroTasks Queue: Web API からの他のすべてのコールバック (setTimeout、setInterval、DOM API、 fetch) は、macroTasks キューに入ります。
イベントループとは何ですか?
これは、タスクを待機し、実行のために呼び出しスタックにタスクをプッシュする無限ループです。 JavaScript はシングルスレッドであるため、優先度に基づいて同期と非同期の両方の操作を処理するための実行順序が維持されます。
-
通常の JS コード: 同期コードが最初に実行され、呼び出しスタックが埋められます。
-
MicroTasks: microTasks キューに入れられたタスクが実行されます。
-
MacroTasks: マクロタスクキューに入れられたタスクが実行されます。
// Programmatic way of how the event loop processes tasks
while (true) {
// Step 1: Execute tasks in the call stack
while (!callStack.isEmpty()) {
const currentTask = callStack.pop();
currentTask(); // Executes the task
}
// Step 2: Process all microtasks
while (!microTasksQueue.isEmpty()) {
const microTask = microTasksQueue.shift();
callStack.push(microTask); // Push microtask to call stack for execution
}
// Step 3: Process one macrotask if available
if (!macroTasksQueue.isEmpty()) {
const macroTask = macroTasksQueue.shift();
callStack.push(macroTask); // Push macrotask to call stack for execution
}
// Break if there's nothing left to process
if (callStack.isEmpty() && microTasksQueue.isEmpty() && macroTasksQueue.isEmpty()) {
break;
}
}
ログイン後にコピー
ワークフローをよりよく理解するために例を見てみましょう
1. setTimeout(() => console.log(1), 2000);
2. Promise.resolve().then(() => {
3. console.log(2);
4. queueMicroTask(() => console.log(3));
5. });
6. Promise.resolve().then(() => {
7. console.log(4);
8. setTimeout(() => console.log(5));
9. });
10. setTimeout(() => console.log(6));
11. console.log(7);
// 7 2 4 3 6 5 1
ログイン後にコピー
2 つのキュー microTasks と macroTasks があると仮定します。コードの実行が開始されると、
-
() => console.log(1) は 2000 ミリ秒で macroTasks キューにプッシュされます。
-
() => { コンソール.ログ(2); queueMicroTask(() => console.log(3)); }) microTasks キューにプッシュされます。
-
() => { コンソール.ログ(4); setTimeout(() => console.log(5)); }) microTasks キューにプッシュされます。
-
() => console.log(6) は 0 ミリ秒で macroTasks キューにプッシュされます。
-
console.log(7) が実行され、コンソールに 7 が出力されます。
- 今度は、イベント ループが microTasks キューでタスクをチェックし、() => を取得します。 { コンソール.ログ(2); queueMicroTask(() => console.log(3)); }) タスクを実行し、コンソールに 2 を出力し、() => をプッシュします。 console.log(3) を microTasks キューに入れます。
- 次に、イベント ループは microTasks キューをチェックし、() => を取得します。 { コンソール.ログ(4); setTimeout(() => console.log(5)); }) タスクを実行し、4 を出力してプッシュ () => console.log(5) を macroTasks キューに 0 ミリ秒で書き込みます。
- 再び、イベント ループは microTasks キューをチェックし、() => を取得します。 console.log(3)) タスクを実行し、コンソールに 3 を出力します。
-
microTasks キューは空になっているため、イベント ループは、macroTaskQueue をチェックし、() => を受け取ります。 console.log(6) を実行し、コンソールに 6 を出力します。
- イベントループは次のタスクを実行します () => microTasks キューにタスクがないことを確認した後、macroTasks から console.log(5) を取得し、コンソールに 5 を出力します.
- イベントループは次のタスクを実行します () => macroTasks から console.log(1) を取得し、コンソールに 1 を出力します。
読んでいただきありがとうございます!このブログが有益で魅力的であると感じていただければ幸いです。不正確な点に気づいた場合、またはフィードバックがある場合は、遠慮なくお知らせください。
以上がイベントループ — JavaScriptの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。