JavaScript マクロタスクとマイクロタスクの実行順序についての簡単な説明

JavaScript マクロタスクとマイクロタスクの実行順序についての簡単な説明

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

JavaScript はシングルスレッドです。つまり、一度に実行できるのは 1 つの処理のみであり、次の処理は前の処理が完了した後にのみ実行できます。その結果、時間のかかるタスクが発生した場合、後続のコードが実行できなくなります。

その前に、同期と非同期を理解する必要があります

1. 同期タスク

    コンソールログ(123);
    コンソールログ(456);
    (i = 1; i <= 5; i++ とします) {
      コンソールにログ出力します。
    } 

名前が示すように、順番に実行する必要がある

2. 非同期タスク

    タイムアウトを設定する(() => {
      console.log('タイマー');
    }, 0)
    console.log('ウルトラマン');

通常の実行順序では、タイマーが一番上なので、最初にタイマーを出力し、次に Ultraman を出力します。

最終結果は、最初に Ultraman が出力され、次にタイマーが出力されます。これは、setTimeout が非同期タスクであるためです。

もう 1 つ知識があります。setTimeout のタイマーは、何ミリ秒遅れても非同期です。ブラウザごとに時間も異なります。ブラウザごとに違いはありますが、最小値は 0 ミリ秒と 4 ミリ秒と定義されています。

2. タスクキュー

上記のコードから、setTimeout は非同期であることがわかります。実行順序の優先順位は、同期コード > 非同期コードです。したがって、タスクキューは 2 つのカテゴリに分かれています。1. 同期タスク 2. 非同期タスク

1. 実行スタック

(1)すべての同期タスクはメインスレッド上で実行され、実行コンテキストスタックを形成します。

(2)メインスレッドの他に「タスクキュー」も存在します。非同期タスクに実行結果がある限り、イベントは「タスク キュー」に配置されます。

(3)「実行スタック」内のすべての同期タスクが実行されると、システムは「タスクキュー」を読み取り、そこにどのようなイベントが含まれているかを確認します。対応する非同期タスクは待機状態を終了し、実行スタックに入り、実行を開始します。

(4)メインスレッドは上記の3番目のステップを継続的に繰り返します。これをイベントループと呼びます。

梨をあげるだけ

二人とも外食に出かけますが、P2は外食する時間を節約します。

簡単に理解した後、非同期タスクにおけるマクロタスクとマイクロタスクについて詳しく見ていきましょう。

個人的な理解: マクロタスクとマイクロタスクは、非同期の 2 つの形式として理解できます。非同期には、マクロタスクとマイクロタスクという 2 つの子があります。

マクロタスク内のメソッド: 1. スクリプト (エントリポイントとして外部同期コードとして理解できます) 2. setTimeout/setInterval

マイクロタスクのメソッド: 1. Promise 2. nextTick

実行順序は、マイクロタスクが最初に出力され、次にマクロタスクが出力される。

証拠なしにコードを言う

    タイムアウトを設定する(() => {
      console.log('タイマー');
    }, 0)
    新しいPromise((resolve) => {
      console.log('同期コード')  
      解決('非同期コード')
    }).then((res) => {
      コンソールログ(res);   
    })
    console.log('ウルトラマン'); 

new Promise はコンストラクタを作成しますが、これは同期プロセスです。一方、.then メソッドは非同期であるため、コードは最初に同期的に実行されます > microtask > macrotask

実行プロセスをより詳しく説明するため、次の図は少し複雑になっています。

これらの写真は組み合わせて

setTimeoutの理解を深める

質問 1: 同期コードが実行された後、setTimeout は 0 からカウントを開始しますか?

    タイムアウトを設定する(() => {
      コンソールログに'setTimeout'と入力します。
    }, 1000);
    console.log('ウルトラマン');
    (i = 0; i < 1000; i++ とします) {
      コンソールログ('');
    } 

ここで、for ループ内では、setTimeout によってタイマー モジュールも開始されることを指摘しておきます。したがって、メイン スレッドが実行されると、タイマー モジュールはすでに実行を開始しているため、実行に 1 秒待つ必要はありません。

(同期が完了したと想定して計測を開始しないでください。)

質問 2: 2 つのタイマーのうち、上のタイマーを最初に実行し、次に下のタイマーを実行する必要がありますか?

テストでは、誰が最初に実行するかを確認するためのタイマーを追加するだけです。

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

タイマーが 2 つある場合、時間の短い方が最初にメイン スレッドで実行されることがわかります。

質問 3: 変数が 0 として定義され、2 つの同一のタイマー イベントが設定されている場合、出力はどうなりますか? (インタビューの質問)

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

これで、タイマー マクロ タスクは同時に実行されるのではなく、順番に実行されることがおわかりいただけたと思います。 !

マクロタスクとマイクロタスクの実行順序に関する面接の質問

    コンソールログ('1');
 
    setTimeout(関数() {
      コンソールログ('2');
      process.nextTick(関数() {
        コンソールログ('3');
      })
      新しいPromise(関数(resolve) {
        コンソールログ('4');
        解決する();
      }).then(関数() {
        コンソールログ('5')
      })
    })
    process.nextTick(関数() {
      コンソールログ('6');
    })
    新しいPromise(関数(resolve) {
      コンソールログ('7');
      解決する();
    }).then(関数() {
      コンソールログ('8')
    })
 
    setTimeout(関数() {
      コンソールログ('9');
      process.nextTick(関数() {
        コンソールログ('10');
      })
      新しいPromise(関数(resolve) {
        コンソールログ('11');
        解決する();
      }).then(関数() {
        コンソールログ('12')
      })
    })

答え:

外部同期コードの最初の実行ラウンド: 1 7

マイクロタスク実行の2回目のラウンド: 6 8

マクロタスクの3回目のラウンド: 最初のsetTimeout: 同期 2 4 マイクロタスク 3 5 2番目のsetTimeout: 同期 9 11 マイクロタスク 10 12

全体の答え: 1、7、6、8、2、4、3、5、9、11、10、12

これで、JavaScript マクロタスクとマイクロタスクの実行順序に関する記事は終了です。JavaScript マクロタスクとマイクロタスクの実行順序の詳細については、123WORDPRESS.COM の過去の記事を検索するか、以下の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。

以下もご興味があるかもしれません:
  • JavaScript のマクロタスクとマイクロタスクの詳細
  • js のマクロタスクとマイクロタスクについての簡単な説明
  • JavaScript マクロタスクとマイクロタスク
  • JavaScript イベント ループ マイクロタスクとマクロタスク キューの原理に関する簡単な説明
  • JavaScript イベント ループとマクロタスクおよびマイクロタスクの原則の分析
  • JS イベントループの仕組み イベントループ マクロタスク マイクロタスク 原理分析
  • JavaScript のマイクロタスクとマクロタスクの説明

<<:  Linux viコマンドの知識ポイントと使い方のまとめ

>>:  よく使用される MySQL 関数の完全なリスト (分類および要約)

推薦する

MySql 学習 3 日目: データ テーブル間の接続とクエリの詳細

主キー:キーワード: 主キー機能: null にすることはできず、一意である必要があります。主キーの...

シェルを使用して複数のサーバーでバッチ操作を実行する方法

目次SSHプロトコルパスワード接続プロセスsshツールssh公開鍵ログインバッチ操作複数サーバーファ...

MySQL Community Server 8.0.12 のインストールと設定方法のグラフィックチュートリアル

MySQL 8 は、NoSQL、JSON などのサポートなど、まったく新しいエクスペリエンスをもたら...

HTML のメタタグの簡単な比較

メタ タグは、ファイル情報を定義し、検索エンジンによる検索を容易にするために Web ページ ファイ...

Nginx インストール エラーの解決方法

1. nginx-1.8.1.tar.gzを解凍する2. fastdfs-nginx-module-...

Windows 10 64 ビット版に MySQL 5.6.35 をインストールするためのグラフィック チュートリアル

1. MySQL Community Server 5.6.35をダウンロードするダウンロードアドレ...

VMware 仮想化 KVM のインストールと展開のチュートリアルの概要

仮想化1. 環境セントオス7.3 selinuxとファイアウォールを無効にする2. 仮想化環境の構成...

HTMLの行間設定方法と問題点

<p></p> の行間隔を設定するには、style="line-h...

開発効率の向上に役立つ 56 個の実用的な JavaScript ツール関数

目次1. デジタルオペレーション(1)指定された範囲内で乱数を生成する2. 配列操作(1)配列の順序...

複数の例で HTML フォームを使用する方法

参考までに、HTMLフォームの使い方を9つの簡単な例で分析します。具体的な内容は次のとおりです。 1...

MySQL のストアド プロシージャを使用して 100 万件のレコードをすばやく生成する方法

序文テストを行う際、大量のデータによる負荷に耐えるプロジェクトの能力をテストするために、通常はテスト...

Vueコンポーネント通信のさまざまな方法の詳細な説明

目次1. 父から息子へ2. 息子から父へ3. 親子関係のないコンポーネントの値の転送4. ヴュークス...

JavaScript 中断要求に対するいくつかの解決策の詳細な説明

目次1 約束呼び出しチェーンを中断する約束を破る中止メソッドのラッピング - Axios の Can...

Vueはショッピングカート決済機能をシミュレートします

この記事では、ショッピングカート決済機能を実現するためのVueの具体的なコードを例として紹介します。...

image/x-png の ContentType について

これにより、png ファイルのアップロードも不可能になりました (後で情報を調べたところ、レジストリ...