ホームページ > 記事 > ウェブフロントエンド > JavaScriptにおけるイベントループ(Event Loop)の実行シーケンス
この記事はJavaScriptにおけるイベントループ(Event Loop)の実行シーケンスに関するものなので、困っている方は参考にしていただければ幸いです。
簡単な紹介: EvenLoop キュー内の Promise.resove、setTimeout、setImmediate、process.nextTick の実行順序について説明します
問題の原因
イベント ループは、
例1: setTimeout(function(){console.log(1)},0); console.log(2) //输出2,1
など、「タスク キュー」から周期的にタスクを読み取るメイン スレッドを指します。上の例では、同期タスクがメインスレッドが最初に実行され、メインスレッドがスレッドタスクを実行した後、イベントループからタスクが読み込まれるため、最初に2が出力され、次に1が出力されます。
イベント ループがタスクを読み取る順序は、タスク キュー (ジョブ キュー) 内のさまざまなタスク読み取りルールの制限によって異なります。たとえば、次の例では、
例2: setTimeout(function () { console.log(3); }, 0); Promise.resolve().then(function () { console.log(2); }); console.log(1); //输出为 1 2 3
出力 1 が最初に実行されます。メインスレッドで同期タスクが最初に実行されるため、問題はありません。ここで問題となるのは、setTimeout と Promise の実行優先順位です。次にタスクが定義されます。
ジョブ キュー内のキューは、マクロタスクとマイクロタスクの 2 種類に分けられます。実行順序の規則を見てみましょう。
macro-task队列包含任务: a1, a2 , a3 micro-task队列包含任务: b1, b2 , b3
の実行順序が次のとおりであると仮定します。まず、マルコタスク キューの先頭のタスク、つまり a1 (a1) を実行します。は同期のメインタスクを表します) タスクの実行が完了したら、マイクロタスクキュー内のすべてのタスクを実行します。つまり、b1、b2、b3 を (非同期的に) 実行します。実行後、マイクロタスク内のタスクをクリアし、タスク内の 2 番目のタスク (非同期) を順番にループします。
マクロタスクキューとマイクロタスクキューの実行順序を理解した後、実際のシナリオでこれら 2 種類のキューに実際に含まれるタスクを見てみましょう (例としてノード V8 エンジンを取り上げます)。ノード V8 では、これら 2 つのタイプの実際のタスク順序は次のとおりです。
マクロタスク キューには実際にタスクが含まれます:
script(主程序代码)[对应上方的a1],setTimeout, setInterval, setImmediate, I/O, UI rendering
マイクロタスク キューには実際にタスクが含まれます:
process.nextTick, Promises, Object.observe, MutationObserver
これから得られる実行順序は次のようになります:
script(主程序代码)—>process.nextTick—>Promises...——>setTimeout——>setInterval——>setImmediate——> I/O——>UI rendering
ES6 では、マクロタスク キューは ScriptJobs とも呼ばれ、マイクロタスクは PromiseJobs
(1) setTimeoutとpromise
例3: setTimeout(function () { console.log(3); }, 0); Promise.resolve().then(function () { console.log(2); }); console.log(1);
(2) process.nextTickとpromise、setTimeout
例子4: setTimeout(function(){console.log(1)},0); new Promise(function(resolve,reject){ console.log(2); resolve(); }).then(function(){console.log(3) }).then(function(){console.log(4)}); process.nextTick(function(){console.log(5)}); console.log(6); //输出2,6,5,3,4,1
(3) より複雑な例
setTimeout(function(){console.log(1)},0); new Promise(function(resolve,reject){ console.log(2); setTimeout(function(){resolve()},0) }).then(function(){console.log(3) }).then(function(){console.log(4)}); process.nextTick(function(){console.log(5)}); console.log(6); //输出的是 2 6 5 1 3 4
これらの例はご判断ください。実行順序に従って理由を説明します。ここでは 1 つずつ説明しません。
以上がJavaScriptにおけるイベントループ(Event Loop)の実行シーケンスの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。