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 タグの短縮形 (推奨)

推薦する

MySQLのトランザクション特性とレベル原則の分析

1. トランザクションとは何ですか?データベース トランザクション (略称: トランザクション) は...

CentOS 7.5 が Varnish キャッシュサーバー機能を導入

1. ワニスの紹介Varnish は、高性能なオープンソースのリバースプロキシサーバーおよび HTT...

MySQLがサブクエリと結合の使用を推奨しない理由

ページ分割されたクエリを実行するには: 1. MySQL の場合、サブクエリと結合の使用は推奨されま...

HTMLのインライン要素とブロックレベル要素とは何か、またそれらの違いは何ですか

以前の就職面接で面接官が尋ねた質問を覚えています。「インライン要素とは何ですか。ブロックレベル要素と...

Linux 負荷分散 LVS の詳細な理解

目次1. LVS 負荷分散2. 負荷分散LVSの基本紹介3. LVSアーキテクチャ3.1 ロードバラ...

角度でechartsマップを使用する詳細な説明

目次echartの初期化アプリベースチャートコンポーネントhtml CS app-base-char...

CSS3 のメディアクエリと rem レイアウトを組み合わせてモバイル画面に適応

CSS3 構文: (750 ピクセルのデザインの場合、1rem = 100 ピクセル) @media...

MySQL がデュアルマスターで構成されている場合にデータループの競合を回避する方法

あなたはこの質問について考えたことがあるでしょうか?デュアルアクティブが構成されている場合、データル...

Mysql5.7.18 のインストールとマスタースレーブレプリケーションの詳細なグラフィック説明

CentOS6.7にmysql5.7.18をインストールする 1. /usr/localディレクトリ...

Element UI で自動サイズ調整テキストエリアの高さを設定する方法

Element UIのtextarea input自動サイズに設定すると、テキストボックスのデフォル...

CentOS 8 に htop をインストールする方法のチュートリアル

システムをインタラクティブに監視したい場合は、htop コマンドが最適な選択肢の 1 つです。 ht...

VueはOSSを使用して画像や添付ファイルをアップロードします

OSS を使用して Vue プロジェクトに画像や添付ファイルをアップロードするここでは、写真のアップ...

完全バックアップとポイントインタイムバックアップにmysqldumpを使用する方法

Mysqldump は MySQL の論理バックアップに使用されます。高速ではありませんが、柔軟性が...

Tencent Cloud Serverをゼロから導入する方法

初めての投稿ですので、間違いや問題点などありましたら、コメント欄で指摘していただければ、今後改善させ...

ネイティブ js が携帯電話のプルダウン更新を模倣

この記事では、携帯電話のプルダウンリフレッシュを模倣したjsの具体的なコードを参考までに共有します。...