ブラウザのJSイベントループメカニズム

ディレクトリ

  • イベントループメカニズム
  • マクロタスクとミクロタスク
  • ケーススタディ
  • 参考資料

1.イベントループメカニズム

ブラウザイベントループメカニズム

JSコードのブラウザー実行は、大きく3つのステップに分けられ、これら3つのステップの往復がJSイベントループメカニズムを構成します(図を参照)。

最初のステップ: JSコード全体またはコールバック関数(つまり、マクロタスク)をメインスレッド(JSエンジンスレッド)で実行し、実行中にオブジェクトをヒープに格納し、基本的な型と関数をスタック(スタック)に追加します(スタック)、実行後にヒープが解放されるか、スタックが終了します。このマクロタスクの実行後、マイクロタスクキュー(マイクロタスクキュー)が空かどうかを判定し、空でない場合はすべてのマイクロタスクを順番に取り出して実行します。このプロセス中にWeb APIがトリガーされると、2番目のステップが実行されます。

2番目のステップ: Web APIを呼び出し、必要に応じてコールバック関数をイベントキューに追加します。例えば、実装されsetTimeout(callback1, 1000)、それがタイマーを作成し、タイマーが満了するまで、タイマーの期限が切れた待ち時間を監視し、別のスレッド(ブラウザが定期的にスレッドをトリガ)で、対応するコールバックがされますcallback1イベントコールバックスタックに参加します。

ステップ3:最初のステップでのマイクロタスクの実行が完了した後、イベントコールバックスタック(イベントキュー)が空かどうかを判断します。空でない場合は、最初にキューに入るコールバック関数を取り出して実行します。実行プロセスは最初のステップと同様です。空の場合は、必要に応じてメインスレッドを待機または一時停止します。


補足:ブラウザーのコアはマルチスレッドであり、常駐スレッドは、ブラウザーGUIレンダリングスレッド、JavaScriptエンジンスレッド、ブラウザータイミングトリガースレッド、ブラウザーイベントトリガースレッド、およびブラウザーhttp非同期要求スレッドです。


2.マクロタスクとマイクロタスク

マクロタスク:スクリプト(全体的なコード)、setTimeout / setInterval、I / O、UIレンダリングなど

マイクロタスク:Promise、MutationObserverなど


JSコード実行プロセス-マクロタスクとマイクロタスクの実行の概略図:

マクロタスクとマイクロタスクの実行の概略図

図に示すように、JSの実行中は、まずマクロタスクが実行され、次にこのマクロタスクによって生成された対応するマイクロタスクが実行され、実行が完了した後、後続のマクロタスクが何度も実行されます。


3.ケース分析

ブラウザーを使用する:Chromeバージョン80.0.3987.163

最初のグループ:

setTimeoutとPromiseを比較する

console.log('start')

setTimeout(() => {
  console.log('setTimeout')
}, 0);

Promise.resolve().then(() => {
  console.log('microtask: promise')
})

console.log('end')

結果:

setTimeoutとPromiseを比較する

分析:

JSイベントループメカニズムを分析します。まず、スクリプト(全体コード)はマクロタスクです。実行後、「start」と「end」を順次出力し、このプロセスで生成されたマイクロタスク、つまりpromisのコールバックを実行します。その後、「microtask:promise」を出力します;このプロセスでは、Web APIのsetTimeoutも呼び出され、タイマーが作成され、期限切れ後にコールバックがイベントコールバックスタックに追加され、コールバック(2番目のマクロタスク)を実行して、「setTimeout」を出力します。予想通り、ブラウザ操作の出力と一致しています。


2番目のグループ:

マクロタスクとミクロタスクの実行順序の比較

function func1() {
  console.log('func1')
  Promise.resolve().then(() => {
    console.log('microtask.promise1')
  })
}

function func2() {
  console.log('func2')
  Promise.resolve().then(() => {
    console.log('microtask.promise2')
  })
}

function main() {
  func1()
  func2()
  setTimeout(func1, 0);
  setTimeout(func2, 0);
}

main()

結果:

マクロタスクとミクロタスクの実行順序の比較

分析:

出力結果からわかるように、マクロタスクが実行されると、対応するすべてのマイクロタスクが実行され、実行が完了すると、後続のマクロタスクが期待どおりに何度も実行されます。


4.リファレンス

並行性モデルとイベントループ

JavaScriptイベントループ

JavaScriptイベントループの説明

HTMLシリーズ:マクロタスクとマイクロタスク

【翻訳】お約束/ A +仕様

おすすめ

転載: www.cnblogs.com/forcheng/p/12746392.html