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

推薦する

iframe に関するいくつかの発見と考察

この物語は、今日の予期せぬ発見から始まります。同社には複数のウェブサイトがある。友達リンクにはお互い...

HTML/CSSにおける記号論の詳細な説明

この記事では、ソシュールの言語哲学などの理論に基づいて、CSS の class 属性は不要であると主...

JavaScriptアップロードファイル制限パラメータケースの詳細な説明

プロジェクトシナリオ: 1. アップロードファイルの制限関数: 1. フロントエンド操作による異常な...

CSS3 カウントダウン効果

成果を達成する実装コードhtml <div クラス = 'ラッパー'> ...

Vueでeslintを使用する方法の詳細な説明

目次1. 説明2. 関連する依存パッケージをダウンロードする3. 設定ファイル .eslintrc....

Linux カーネル デバイス ドライバー 高度な文字デバイス ドライバーのメモ

/****************** * 高度な文字デバイス ドライバー ***********...

mysql のファイル mysql-bin.000001 とは何ですか? 削除できますか?

ポートを使用して MySQL をインストールした後、しばらくすると /var の容量が不足しているこ...

親子コンポーネントの通信を解決するための3つのVueスロット

目次序文環境の準備カテゴリコンポーネントアプリのコンポーネント1. デフォルトスロット2. 名前付き...

Nginx を使用してポート転送 TCP プロキシを実装する例

目次需要背景Nginx を使用する理由は何ですか? Nginx によるポート転送依存関係をインストー...

単一/複数行テキストを含む div を垂直方向に中央揃えする N 通りの方法 (高さ不明/高さ固定)

この問題について話すとき、垂直方向の中央揃えを設定するための vertical-align 属性が ...

Nginx リバース プロキシでセッション永続性を実装する 2 つの方法の詳細な説明

1. ip_hash: ip_hash は、送信元アドレス ハッシュ アルゴリズムを使用して、サーバ...

React antd タブの切り替えによりサブコンポーネントが繰り返し更新される

説明する: Tabs コンポーネントが切り替わると、TabPane に含まれる同じサブコンポーネント...

Vueアイコンセレクターのサンプルコード

出典: http://www.ruoyi.vip/ 'vue' から Vue をイン...

JavaScript における継承の 3 つの方法

継承する1. 継承とは何か継承: まず、継承とは関係、つまりクラス間の関係です。JS にはクラスはあ...

Centos7.5 は mysql5.7.24 バイナリ パッケージの展開をインストールします

1. 環境整備:オペレーティング システム: CentOS Linux リリース 7.5.1804 ...