jsのイベントループ機構の解析

jsのイベントループ機構の解析

序文

ご存知のとおり、JavaScript は本質的にシングルスレッドですが、ブラウザは非同期リクエストを非常にうまく処理できます。なぜでしょうか?この背後にある原理は、イベント ループ メカニズムと大きく関係しています。

イベントループを調べる前に、ブラウザ実行スレッドを理解する必要があります~~

ブラウザのレンダリング プロセスはマルチスレッドです。ブラウザ内の各タブは独立したプロセスを表します。ブラウザ カーネルはブラウザのマルチプロセスの 1 つであり、主にページのレンダリング、スクリプトの実行、イベント処理などを担当します。含まれるスレッドは次のとおりです

GUI レンダリング スレッド: ページのレンダリング、HTML および CSS の解析を行って DOM ツリーを形成します。
JS エンジン スレッド: コード、ユーザー入力、ネットワーク要求を解釈して実行します。
イベント処理スレッド: クリック、マウス、その他のインタラクティブなイベントが発生すると、イベント関数がキューに入れられます。
タイマーがスレッドをトリガーします。時間切れになると、実行関数がタスク キューにプッシュされます。
http ネットワーク リクエスト スレッド: ユーザーの get リクエストと post リクエストを処理し、返された結果をタスク キューにプッシュします。

ブラウザのレンダリングプロセスを理解した後は、JS の動作メカニズムも理解する必要があります。 JSの動作メカニズムはイベントループです

実行スタック

JS が実行される環境はホスト環境と呼ばれます。

実行スタック: コール スタックは、さまざまな関数の実行環境を格納するために使用されるデータ構造です。各関数が実行される前に、その関連情報が実行スタックに追加されます。関数が呼び出される前に実行環境が作成され、実行スタックに追加されます。関数が呼び出された後、実行環境は破棄されます。

イベントループ

js のすべてのタスクは、同期タスクと非同期タスクに分けられます。同期タスクは、すぐに実行されるタスクです。同期タスクは通常、実行のためにメインスレッドに直接入ります。一方、非同期タスクは、Ajax ネットワーク リクエスト、setTimeout タイミング関数など、すべて非同期タスクである非同期で実行されるタスクです。非同期タスクは、タスク キュー (先入れ先出し) メカニズムを通じて調整されます。同期タスクと非同期タスクはそれぞれ異なる実行環境に入ります。同期タスクはメインスレッド、つまりメイン実行スタックに入り、非同期タスクはタスクキューに入ります。メイン スレッド内のタスクが完了して空になると、タスク キューが読み取られ、対応するタスクが読み取られ、実行のためにメイン スレッドにプッシュされます。 この一定の繰り返しをイベント ループと呼びます。具体的なプロセスは以下の図の通りです。

イベント ループでは、各ループ操作はティックと呼ばれます。各ティック タスク キーの手順は、次のようにまとめることができます。1. マクロ タスクを実行します (スタックにマクロ タスクがない場合は、イベント キューから取得します)。2. 実行中にマイクロ タスクに遭遇した場合は、マイクロ タスクのタスク キューに追加します。3. マクロ タスクの実行後、現在のマイクロ タスク キュー内のすべてのマイクロ タスクが直ちに実行されます (順番に)。4. 現在のマクロ タスクの実行後、レンダリングのチェックを開始し、その後 GUI スレッドがレンダリングを引き継ぎます。5. レンダリングが完了したら、JS スレッドが引き続き引き継いで次のマクロ タスクを開始します (イベント キューから取得します)。

マクロタスクには主に、スクリプト(コード全体)、setTimeout、setInterval、I/O、UIインタラクションイベント、setImmediate(Node.js環境)が含まれます。
マイクロタスクには主に、Promise、MutaionObserver、process.nextTick(Node.js 環境)が含まれます。

イベントループの例

console.log('スクリプトの開始');
//スクリプト全体が最初のマクロタスクとしてメインスレッドに入り、console.logに遭遇し、スクリプト開始を出力します。
setTimeout(関数() {
  コンソールログに'setTimeout'と入力します。
}, 0);
//setTimeoutに遭遇すると、そのコールバック関数がマクロタスクイベントキューに配布されます Promise.resolve().then(function() {
  コンソールにログ出力します。
}).then(関数() {
  コンソールにログ出力します。
});
// Promise に遭遇すると、その then 関数がマイクロタスク イベント キューに割り当てられ、then1 として記録されます。次に、別の then 関数に遭遇し、マイクロタスク イベント キューに割り当てられ、then2 として記録されます。
console.log('スクリプト終了');
//console.logに遭遇したら、出力スクリプト終了

このように、イベント キューには、マクロ タスク: setTimeout、マイクロ タスク: then1、then2 の 3 つのタスクがあります。まずマイクロタスクthen1を実行し、promise1を出力し、次にthen2を実行し、promise2を出力して、すべてのマイクロタスクをクリアします。

setTimeoutタスクを実行し、setTimeoutを出力します。これまでの出力順序は、スクリプト開始、スクリプト終了、promise1、promise2、setTimeoutです。

要約:

JavaScript はシングルスレッド言語です。非同期操作はイベント ループ キューに配置され、メイン実行スタックの実行を待機します。専用の非同期実行スレッドはありません。

js のイベントループの仕組みについての記事はこれで終わりです。より関連性の高い js イベントループのコンテンツについては、123WORDPRESS.COM の過去の記事を検索するか、以下の関連記事を引き続き閲覧してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。

以下もご興味があるかもしれません:
  • JSのイベントループの仕組みを説明する記事
  • JavaScriptのイベントループの仕組みについて簡単に説明します
  • JavaScriptのイベントループの仕組みの分析
  • JSブラウザイベントループの仕組みの詳しい説明
  • JavaScriptイベントループの仕組みの詳しい説明
  • js イベントループメカニズムの分析例
  • JS のイベントループメカニズムの詳細な例

<<:  MySQL テーブルの読み取り、書き込み、インデックス作成、その他の操作の SQL ステートメントの効率最適化の問題を分析します。

>>:  CentOS8 ネットワークカード設定ファイル

推薦する

MySQLデータベースのトランザクション分離レベルの詳細な説明

データベーストランザクション分離レベルデータベース トランザクションには、低から高まで 4 つの分離...

Postman に基づく HTTP インターフェース テスト プロセスの分析

偶然、素晴らしい人工知能のチュートリアルを発見したので、みんなと共有せずにはいられませんでした。この...

JSはオンラインでのアナウンスのスクロール効果を実現します

この記事では、オンラインアナウンスのスクロール効果を実現するためのJSの具体的なコードを参考までに共...

Nginx リバースプロキシの例の詳細な説明

1. リバースプロキシの例1 1. 効果を達成する(1)ブラウザを開き、www.123.comと入力...

Vue-router は現在の場所 (/path) へのナビゲーションを許可しません。エラーの原因と修正

目次エラーメッセージ原因エラーのデモンストレーション回避策方法1方法2方法3エラーメッセージ現在の場...

HTML文書の基本構造(Webページ作成の基礎知識)

HTMLの動作原理: 1. ローカル操作: ブラウザでhtmlファイルを開く2. リモートアクセス...

ウェブサイトのアクセス速度を向上させるための徹底的な最適化に関するヒント

ウェブサイトのアクセス速度を向上させるための徹底的な最適化に関するヒント。ウェブサイトのアクセス速度...

Linux 上の Nginx に複数のバージョンの PHP をインストールする

サーバーの LNPM 環境をインストールして構成する場合、複数のバージョンの PHP の共存を考慮す...

MySQL InnoDB インデックス拡張の詳細な説明

インデックス拡張: InnoDB は、プライマリ キー列をそのインデックスに追加することで、各セカン...

Docker ベースの Etcd 分散デプロイメントの方法と手順

1. 環境整備1.1 基本環境NTP設定: 省略 #時間の一貫性を確保するためにNTPサービスを設定...

Samba を使用して Linux サーバー上で共有ファイル サービスを構築する方法

最近、私たちの小さなチームは、サーバー上の共有フォルダーを共有して、全員がパブリックリソースドキュメ...

Linux のよく使うコマンドの使い方を詳しく解説(第 2 回)———— テキストエディタのコマンド vi/vim

vi/vim の紹介どちらもマルチモード エディターです。違いは、vim が vi のアップグレー...

Linux カーネルの探究: Kconfig の秘密

Linux 構成/ビルド システムがどのように機能するかを深く理解します。 Linux カーネル構成...

ページにスクロールバーが表示されたときに、スクロールバーがページ幅に影響しないようにする方法

本体の幅をウィンドウの幅に設定します(次のスクリプトで制御されます) $("body&qu...

VueはWebSocketを使用してチャット機能をシミュレートします

この効果は、2つのブラウザが互いにシミュレートしていることを示しています 1. シミュレートされたノ...