ホームページ > 記事 > ウェブフロントエンド > JSブラウザのイベントループの仕組み
この記事では、主に JS ブラウザーのイベント ループの仕組みを紹介します。これは、必要な友人に参考にしていただけるよう、共有します。まず、概念的な内容を理解しましょう。
プロセス、スレッド
JavaScriptエンジンはシングルスレッドです
Web-Worker API は、主にページのブロックの問題を解決するために HTML5 で提案されていますが、JavaScript のシングルスレッドの性質は変わりません。 Web ワーカーについて学びましょう。
JavaScriptのイベントループ機構
JavaScript にはメインスレッドと呼び出しスタック (実行スタック) があり、すべてのタスクは呼び出しスタックに配置され、メインスレッドが実行されるのを待ちます。
JS 呼び出しスタックは、後入れ先出しのデータ構造です。関数が呼び出されると、その関数はスタックの先頭に追加され、実行が完了すると、スタックがクリアされるまでその関数はスタックの先頭から削除されます。
単一スレッド内のJavaScriptタスクは、同期タスクと非同期タスクに分けられます。同期タスクはコール スタック内で順番にキューに入れられ、メイン スレッドの実行を待機します。一方、非同期タスクは、非同期結果が利用可能になった後、登録されたコールバック関数をタスク キュー (メッセージ キュー) に追加し、メイン スレッドが実行されるのを待ちます。アイドル、つまりスタック内 クリアされると、スタックに読み込まれ、メインスレッドによる実行を待ちます。タスクキューは先入れ先出しのデータ構造です。
コールスタック内のすべての同期タスクが実行され、スタックがクリアされた後、この時点でメインスレッドがアイドル状態であることを意味します。順序付けしてスタック実装に配置します。スタックをクリアするたびにタスクキューにタスクがあるかどうかを読み出し、タスクがあれば読み込んで実行するという動作がイベントループを形成します。
タイマーは、指定された時間待機した後、タイマー トリガー スレッドを開始して、読み取りを待機します。実行用のメインスレッド。
タイマーによって指定された遅延ミリ秒数は、実際には正確ではありません。これは、タイマーは、指定された時間に達した場合にのみイベントをタスク キューに配置し、同期されたタスクと既存のタスク キュー内のイベントが完了するまで待機する必要があるためです。完了後はタイマーイベントを読み込んでメインスレッド上で実行するため、途中で時間がかかるタスクが存在する可能性があり、指定した時刻に実行されることは保証できません。
マクロタスク、マイクロタスク
一般化された同期タスクと非同期タスクに加えて、JavaScript シングルスレッドのタスクはマクロタスクとマイクロタスクに細分化できます。
マクロタスクには、スクリプト (コード全体)、setTimeout、setInterval、setImmediate、I/O、UI レンダリングが含まれます。
マイクロタスクには、process.nextTick、Promises、Object.observe、MutationObserver が含まれます。
console.log(1); setTimeout(function() { console.log(2); }) var promise = new Promise(function(resolve, reject) { console.log(3); resolve(); }) promise.then(function() { console.log(4); }) console.log(5);
例ではsetTimeoutとPromiseをタスクソースと呼び、異なるタスクソースから登録されたコールバック関数は異なるタスクキューに入れられます。
マクロタスクとマイクロタスクの概念がわかったところで、JSの実行順序はどうなるのでしょうか?マクロタスクとミクロタスクはどちらを先にすべきでしょうか?
最初のイベント ループでは、JavaScript エンジンはスクリプト コード全体をマクロタスクとして実行し、実行が完了した後、このループ内にマイクロタスクがあるかどうかを検出し、存在する場合はタスクから読み取ります。すべてのマイクロタスクを実行した後、マクロタスクのタスクキュー内のタスク実行を読み取り、すべてのマイクロタスクを実行します。 JSの実行順序は、各イベントループ内のマクロタスク→マイクロタスクとなります。
上記の例では、最初のイベント ループで、コード全体がマクロ タスクとして実行するためにメイン スレッドに入ります。
setTimeoutに遭遇すると、指定された時間が経過するまで待機し、コールバック関数をマクロタスクのタスクキューに入れます。
Promise に遭遇したら、then 関数をマイクロタスクのタスクキューに入れます。
イベントループ全体が完了した後、マイクロタスクのタスクキューにタスクがあるかどうかを検出し、存在する場合はそれを実行します。
最初のサイクルの結果は、1、3、5、4 として出力されます。
次に、マクロタスクのタスクキューに移動し、マクロタスクを順番に取り出し、メインスレッドが実行できるようにスタックに置きます。そして、このループ内のマクロタスクは、setTimeoutによって登録されたコールバック関数です。このコールバック関数を実行した後、このサイクルにはマイクロタスクがないことがわかり、次のイベント サイクルの準備が整いました。
マクロタスクキューに実行すべきタスクがないことが検出された場合、イベントループは終了します。
最終結果は 1,3,5,4,2 です。
上記がこの記事の全内容です。その他の関連コンテンツについては、PHP 中国語 Web サイトをご覧ください。
関連する推奨事項:
以上がJSブラウザのイベントループの仕組みの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。