Javascript 操作メカニズム イベントループ

Javascript 操作メカニズム イベントループ

1. 4つのコンセプト

1. JavaScriptはシングルスレッドです

シングルスレッドとは、 jsコードを上から下まで同期的にしか実行できず、同時に実行できるタスクは 1 つだけであることを意味します。これにより、実行時間が長いタスクや実行時間が不確実なタスクが、他のタスクの正常な実行をブロックすることになります。 Event Loopが表示されるのは、この問題を解決するためです。

2. タスクキュー

上記のキューイング問題を解決するために、タスク キューが作成されます。ブラウザに結果を伴う非同期タスクがある場合、それは将来の実行のためにタスク キューに追加され、他のタスクはメイン スレッドで同期的に実行されます。

ここで注意すべき点は、タスク キューにタスクを追加するタイミングは、非同期タスクの結果が出た後であるということです。実際、タスク キューに存在するのは、非同期タスクのコールバック関数です。

3. 同期タスクと非同期タスク

Js プログラムにおける同期タスクはメインスレッドで実行されるタスクを指し、非同期タスクはタスクキューに入るタスクを指します。

4. JavaScript実行スタック

すべての同期タスクはメインスレッド上で実行され、実行スタックを形成します。メインスレッド上のタスクが完了すると、タスクはタスクキューから取り出されて実行されます。

var name = "zhouwei";

タイムアウトを設定する(() => {
    コンソールログ(1);
}, 1000);

console.log(名前);


上記のコードは、ブラウザでは次のように実行されます。プログラムのグローバル実行環境のコードは、main 関数にラップされたコードとして理解されます。このコードの実行スタックは、次の図に示すように変化します。

  • コードの実行を開始し、 mainタスク (実行のためにスタックにグローバル コード) をプッシュし、非同期タスクに遭遇したとき ( setTimeoutの後)。
  • ブラウザは非同期タスクを引き継ぎ、1 秒後に非同期タスクの結果 (コールバック関数) をタスク キューに追加します。
  • 実行スタック内の同期タスクが完了します。この時点で、タスク キューは空 (1 秒未満) であり、実行スタックも空です。
  • 非同期タスクは結果が出ると、まずタスク キューに入ります (非同期タスクが多数ある場合があるため)。
  • 実行スタックはタスクをタスク キューから取り出し、同期的に実行を開始します。
  • 手順 5 を繰り返します。

イベントループ

Js 実行スタックがタスク キューからタスクを継続的に読み取り、実行するプロセスをEvent Loop

タスク キューには非同期タスクの結果が格納されることはわかっていますが、非同期タスクとは何でしょうか?

  • 1. イベント

Javascriptには多くのイベントがありますが、それらはすべて非同期タスクです。ブラウザが引き継ぎます。イベントがトリガーされると、イベント コールバックがタスク キューに追加され、Js 実行スタックにタスクがない場合に実行されます。

  • 2. HTTPリクエスト
  • 3. タイマー
  • 4. requestAnimationFrameなど

macrotaskmicrotask
タスク キューとEvent Loopを理解した後、Js 実行スタックがタスク キューからタスクを読み取って実行することはわかりますが、この特定のプロジェクトについては明確ではありません。ここでは、イベント ループを理解するのに役立つマクロタスクとマイクロタスクの概念を紹介します。

タスクキューに入る非同期タスクコールバックは、マクロタスクとマイクロタスクに分けられます。マクロタスクとマイクロタスクを実行するための Js 実行スタックのルールを下図に示します。

Js 実行スタックは、最初にマクロ タスク (グローバル コード) を実行し、タスク キューからすべてのマイクロ タスクを読み取り、UI レンダリング (ブラウザー レンダリング インターフェイス) を実行し、タスク キューからマクロ タスクを読み取り、すべてのマイクロ タスクを実行し、UI レンダリングを実行し、…

イベント ループの各ラウンドが終了すると (1 つのマクロ タスク + すべてのマイクロ タスク)、ブラウザーはインターフェイスのレンダリングを開始します (レンダリングが必要な UI がある場合、それ以外の場合は UI レンダリングは実行されません)。UI UI rendering終了すると、イベント ループの次のラウンドが開始されます。

マクロタスクとは何ですか?

  • タイムアウトの設定
  • 間隔の設定
  • setImmediate (ノード)
  • requestAnimationFrame (ブラウザ)
  • I/O (イベントコールバック)
  • UIレンダリング(ブラウザレンダリング)

マイクロタスクとは何ですか?

  • 約束
  • process.nextTick (ノード)
  • MutationObserver (DOM の変更を検出するために最新のブラウザが提供する Web インターフェース)

setTimeout 遅延の問題

一般的に、コード内のsetTimeoutのコールバックの実行時間は、設定された時間よりも長くなります。 これは、 setTimeoutで指定された時間が経過した後、コールバック関数がタスク キューに追加されるものの、この時点で Js 実行スタックで実行中のタスクが存在する可能性があるためです。このコールバックは、Js 実行スタック内のタスクが完了するまで待機してから実行する必要があります。これがsetTimeout遅延問題です。

3. 実戦

次のコード出力を練習してください。

コンソールログ(1);

タイムアウトを設定する(() => {
    コンソールログ(2);
    Promise.resolve().then(() => {
        コンソール.log(3)
    });
});

新しいPromise(resolve => {
    コンソールログ(4);
    タイムアウトを設定する(() => {
        コンソールログ(5);
    });
    解決する(6)
})。次に、データ => {
    コンソールにログ出力します。
})

タイムアウトを設定する(() => {
    コンソール.log(7);
})

コンソールログ(8);

この質問を分析するには、上で説明した js 実行メカニズムを使用します。

1: グローバルタスクで同期コード出力を実行します。

1
4
8

ここで注意すべき点は、 Promiseが受け入れるhandle関数は同期タスクであるのに対し、 thenメソッドは非同期タスクであるため、4 が直接出力されることです。

2: この時点で、タスク キューには 3 つのsetTimeoutマクロ タスクと 1 つのPromiseマイクロ タスクがあります。

// この時点でのマクロタスクは setTimeout(() => {
    コンソールログ(2);
    Promise.resolve().then(() => {
        コンソール.log(3)
    });
});

タイムアウトを設定する(() => {
    コンソールログ(5);
});


タイムアウトを設定する(() => {
    コンソール.log(7);
})

// この時点で、マイクロタスクは then(data => {
    コンソールにログ出力します。
})

マイクロタスクを実行し、出力: 6

3: 最初のマクロタスクを実行します

タイムアウトを設定する(() => {
    コンソールログ(2);
    Promise.resolve().then(() => {
        コンソール.log(3)
    });
});


出力: 2

このマクロタスクでは、マイクロタスクがタスク キューに追加されます。この時点で、タスク キューには新しいマイクロタスクがあります。

4: マイクロタスクを実行し、出力: 3

それから(() => {
   コンソール.log(3)
});


5: ルールに従ってタスクの実行を継続します。出力: 5、7

全体的な出力は次のとおりです。

1、4、8、6、2、3、5、7

これがあなたの答えですか?

要約:

  • javascritpタスクは同期タスクと非同期タスクに分けられます
  • 同期タスクはメインスレッド (Js 実行スタック) で実行され、非同期タスクは他のスレッドに引き継がれ、非同期タスクに結果がもたらされた後、そのコールバックがタスク キューに追加されます。
  • タスク キュー内のタスクは、マクロタスクとマイクロタスクに分けられます。 Js 実行スタックは常に最初にマクロ タスクを実行し、次にすべてのマイクロ タスクを実行します...

Javascriptのイベント ループの動作メカニズムに関するこの記事はこれで終わりです。Javascript のイベント ループの動作メカニズムに関するより関連性の高いコンテンツについては、123WORDPRESS.COM の以前の記事を検索するか、以下の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。

以下もご興味があるかもしれません:
  • JavaScriptの動作メカニズムの詳細な説明とイベントループについての簡単な説明
  • JavaScriptの動作の仕組みのイベントループ(Event Loop)の詳しい解説

<<:  MySQLでページングクエリを実装する方法

>>:  いくつかの CSS3 タグの短縮形 (推奨)

推薦する

hasLayout によって発生する CSS バグの一覧

IE には長い間問題がありました。誰もがテストを受けたとき、誰もが笑顔でしたが、それはただのニヤニヤ...

Vue3.0 + TypeScript + Vite初体験の詳しい説明

目次プロジェクトの作成プロジェクト構造メイン.jsアプリ.vue:設定コンポジションAPI参照反応的...

mysql スケジュールタスク (イベント イベント) の詳細な説明

1. イベントの簡単な紹介イベントは、MySQL が特定の時間に呼び出す手続き型データベース オブジ...

MySQL 起動失敗の問題とシナリオ分析

1. ワンストップソリューション1. 問題の分析と特定 # MySQL設定ファイルを見つけて、MyS...

JavaScriptのプロトタイプオブジェクトを徹底的に理解しましょう

目次1. プロトタイプとは何ですか? 1.1 関数プロトタイプオブジェクト1.2 コンストラクタを使...

MySQLを監視するためのbinlogログ解析ツールの詳しい説明:Canal

Canal は、Java を使用して開発された Alibaba のオープンソース プロジェクトです...

モバイル端末での Vue2.x Picker のグローバル呼び出し実装

目次ピッカーコンポーネントとはピッカーコンポーネントの問題解決オプションの説明解決ディレクトリ部門P...

今日と昨日の 0:00 タイムスタンプを取得する MySQL の例

以下のように表示されます。昨日: UNIX_TIMESTAMP(CAST(SYSDATE() AS ...

HTML文書におけるol要素の数値制限に関する議論

一般的に言えば、HTML ドキュメント内で極端に大きな <ol> リストに遭遇する可能性...

Dockerのプロセスとイメージを実行するための基本コマンドの詳細な説明

目次1. ワークフローを実行する2. ミラーリングの基本コマンド1. ワークフローを実行するDock...

HTMLは入力完了を検出する機能を実装する

入力が進行中かどうかを検出するには、「onInput(event)」を使用しますコンテンツが変更され...

ウェブデザインと制作に関する科学的原則と提案の要約

<br />ネットワーク設計の分野では、アイトラッキングに関する研究が非常に盛んに行われ...

SQL と MySQL のステートメント実行順序の分析

今日、問題が発生しました: MySQL の insert into、update、delete ステ...

mysql5.5.28 のインストール チュートリアルは非常に詳細です。

参考までにmysql5.5.28のインストールチュートリアルです。具体的な内容は次のとおりです。イン...

MySQL InnoDB のロック機構の詳細な説明

前面に書かれたデータベースは本質的に共有リソースであるため、同時アクセスのパフォーマンスを最大化する...