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 関数の完全なリスト (分類および要約)

ブログ    

推薦する

Linux コマンドラインでメールを送信する 5 つの方法 (推奨)

シェル スクリプトで電子メールを作成する必要がある場合は、コマンド ラインから電子メールを送信する知...

JavaScript スタイル オブジェクトと CurrentStyle オブジェクトのケース スタディ

1. スタイルオブジェクトスタイル オブジェクトは単一のスタイル宣言を表し、スタイルが適用されている...

Ubuntu 20.04 では、隠し録音ノイズ低減機能が有効になります (推奨)

最近、 Ubuntu 20.04でkazamを使用して録音しているときに、問題が見つかりました。シス...

Vueはページに透かし効果を追加する機能を実装します

最近、あるプロジェクトに取り組んでいたとき、ページに透かし効果を追加するように依頼されました。さっそ...

IIS7 IIS8 リバースプロキシルールの記述、インストール、構成方法

目的: ステーションAをステーションBのセカンダリディレクトリとして扱うのように: http://w...

MySQL のデータベース パフォーマンスに影響を与える要因の説明

データベースのパフォーマンスに関する話面接では、「データベースにどのくらい精通していますか?」など、...

MySQL データ分析ストレージエンジンの例の説明

目次1. 事例紹介2. システムのデフォルトのストレージエンジンとデフォルトの文字セットを表示する3...

mysql 8.0.18 mgr のインストールと切り替え機能

1. システムインストールパッケージ yum -y インストール make gcc-c++ cmak...

Dockerを使用してSpring Bootプロジェクトをデプロイする手順

目次シンプルなSpringbootプロジェクトを作成する1. pom.xmlでSpring Boot...

ReactでCSSをエレガントに書く方法

目次1. インラインスタイル2. インポート方法を使用する3.cssモジュールのエクスポート4. ス...

Centos7.9 で独立したメール サーバーを構築するための詳細な手順

目次序文1. イントラネットDNS AレコードとMXレコードを構成する2. メールサーバの初期化設定...

MySQL の挿入およびバッチ ステートメントのいくつかの例の詳細な説明

目次序文1.無視を挿入2. 重複キーの更新時3. を置き換える4.存在しない場合は挿入する5. デー...

フォーム検証機能を実装するためのネイティブ js

目次開発の際には、機能を段階的に分析して実装することで、明確な考え方を保つことができます。 1. フ...

この記事では、6つの負荷分散技術の実装方法をまとめます(要約)

ロード バランシングは、サーバー クラスタの展開でよく使用されるデバイスです。マシンのパフォーマンス...

JSでHTML本文のスタイルを変更する

目次1. 本来の定義2. JS操作、幅の変更を例に3. 効果: 幅が変更されました 1. 本来の定義...