js のマクロタスクとマイクロタスクについての簡単な説明

js のマクロタスクとマイクロタスクについての簡単な説明

マクロタスクとマイクロタスクに関する質問です。

setTimeout(関数(){
  コンソールログ('1')
});
 
新しいPromise(function(resolve){
  コンソールログ('2');
     解決する();
}).then(関数(){
 コンソールログ('3')
});
 
コンソールログ('4')

上記のコードの実行順序は何ですか?

友達の中には、2、4、1、3と答える人もいるかもしれません。

おそらく、次のように考えているのでしょう。js が 1 行ずつ実行されることを知らないのでしょうか。SetTimeout setTimeout非同期なので、最後に置かれます。下に行くと、 console.log(2)が実行されます。.then() は非同期なので、最後に置かれます。次に、 console.log(4);次に、非同期キューに移動し、最初にconsole.log(1);次にconsole.log(3)実行されます。

ちょっとパニックになったので、ブラウザに貼り付けて見てみました。

信じられない

混乱しながらも、JavaScriptの動作の仕組みをじっくり勉強するしかありません!

1. JavaScriptについて

JavaScriptはシングルスレッド言語です。つまり、一度に 1 つのタスクしか完了できません。実行するタスクが複数ある場合は、それらをキューに入れて、キューに従って実行する必要があります (前のタスクが完了してから次のタスクを実行します)。

2. JavaScript イベントループ

js はシングルスレッドなので、ウィンドウが 1 つしかないカフェテリアのようなものです。学生は 1 人ずつ並んで食事を取る必要があります。同様に、js タスクも 1 つずつ順番に実行する必要があります。このモードは実行が簡単ですが、将来的に需要、トランザクション、リクエストが増加すると、このシングルスレッド モードの実行効率は必然的に低くなります。 1 つのタスクの実行に長い時間がかかる場合、その間に後続のタスクを実行することはできません。

ニュースに含まれる高解像度の写真の読み込みが非常に遅いのはよくあることです。写真が完全に表示されるまで、Web ページが停止したままでよいのでしょうか?この問題を解決するために、 JavaScript 言語ではタスク実行モードを同期と非同期に分けます。

  • 同期モード:これは前述の実行モードです。後のタスクは前のタスクが終了するのを待ってから実行されます。プログラムの実行順序はタスクの配置順序と一致し、同期されます。
  • 非同期モード:各タスクには 1 つ以上のcallback関数があります。前のタスクが完了すると、次のタスクの代わりにコールバック関数が実行されます。次のタスクは、前のタスクの完了を待たずに実行されます。そのため、プログラムの実行順序はタスクの配置順序と一致しず、非同期になります。

地図の内容を言葉で表現すると次のようになります。

  • 同期タスクと非同期タスクは、それぞれ異なる実行「場所」に入ります。同期タスクはメイン スレッドに入り、非同期タスクはEvent Tableに入り、関数を登録します。
  • 指定された処理が完了すると、 Event Tableこの関数をEvent Queueに移動します。
  • メインスレッドのタスクが完了して空になると、 Event Queueに移動して対応する関数を読み取り、メインスレッドで実行します。
  • 上記のプロセスは継続的に繰り返され、 Event Loopと呼ばれることもあります。

コード式の場合:

データ = [] とします。
$.ajax({
    url:blog.csdn.net、
    データ:データ、
    成功:() => {
        console.log('送信に成功しました!');
    }
})
console.log('コード実行が終了しました');


上記は単純な Ajax リクエスト コードです。

  • ajax Event Tableに入り、コールバック関数successを登録します。
  • console.logを実行します (「コードの実行が終了しました」)。
  • ajax イベントが完了し、コールバック関数success Event Queueに入ります。
  • メインスレッドはEvent Queueからコールバック関数のsuccessを読み取り、実行します。

上記のテキストとコードを通じて、js の実行順序について大まかに理解していただけたと思います。しかし、これは、何人かの友人が 2、4、1、3 と答えた理由でもあります。

しかし、実際には、非同期キューにはまだトリックが残っています。面接の質問では、 setTimeoutpromise.then()両方とも非同期キューにあります。次に、それらのテクニック(マクロタスクとマイクロタスク)について説明します。

3. マクロタスクとマイクロタスク

マクロタスクとマイクロタスクは標準ではないため、人によって理解の仕方は異なりますが、js では実行順序が統一されています。

マクロタスク:

#ブラウザノード
<script> 全体のコード
タイムアウトの設定
間隔の設定
即時設定x
リクエストアニメーションフレーム x
アヤックス
DOM イベント

マイクロタスク:

#ブラウザノード
プロセス.nextTick x
ミューテーションオブザーバー x
Promise.then catch finally

マクロタスクには以下が含まれます: <script> 全体のコード、 setTimeoutsetIntervalsetImmediateAjax 、DOM イベント
マイクロタスク: process.nextTickMutationObserverPromise.then catch finally

process.nextTickは大きく異なり、異なるノードは均一に実行されず、標準がありません。
マイクロタスクはマクロタスクよりも早く実行される

ヒント: <script> コード全体をマクロ タスクに入れる人もいますが、私は個人的には好きではありません。私の場合は、実行のメイン スレッドだけです。私は個人的に、マクロ タスクとマイクロ タスクの両方を非同期タスクに分類しています。

面接の質問をもう一度見てみましょう。

//コールバックは非同期タスクです setTimeout(function(){//macro task console.log('1')
});
 
新しいPromise(function(resolve){
  console.log('2');//メインスレッドを同期するresolve();
}).then(function(){//microtask console.log('3')
});
 
console.log('4') //メインスレッドを同期する

2: 同期の最初のものなので、最初の

4: 同期中の2番目なので、2番目

3: 非同期のマイクロタスク

1: マクロタスクは非同期なので、2番目

したがって、結果は 2、4、3、1 です。

さらに、これについて詳しく説明しましょう。

setTimeout(() =>{//マクロタスクキュー1
  console.log('1'); //マクロ タスク チーム 1 タスク 1

  setTimeout(() =>{//マクロタスクキュー3(マクロタスクキュー1内のマクロタスク)
    コンソールログ('2')
  }, 0)

  新しいPromise(resolve => {
    解決する()
    console.log('3') //マクロタスクキュー1タスク2
  }).then(() =>{//マクロタスク キュー 1 のマイクロタスク console.log('4')
  })

}, 0)
 
setTimeout(() =>{//マクロタスクキュー2
  コンソールログ('5')
}, 0)

console.log('6') //メインスレッドを同期する

コード全体を実行します (マクロタスク) console.log('6') >> マクロタスクキュー 1 とマクロタスクキュー 2 は非同期です (順番に実行されます)

マクロタスクキュー1: =>

コンソールログ('1')

コンソールログ('3')

console.log('4') //マクロタスク内のマイクロタスク

残りはマクロタスク内のマクロタスク(console.log(2))であるため、最初に実行されず、後でタスクキューにスローされます。

マクロタスクキュー2: =>

コンソールログ('5')

マクロタスク キュー 1 のマクロタスク 3: =>

コンソールログ('2')

上記のコードでは何が出力されますか?

4. マクロタスクとマイクロタスクを拡張する

上記の質問は複雑です。よく考えてみてください。この複雑な状況で、どのように一つずつ実行すればよいのでしょうか。

  • 6: 最初の同期メインスレッドなので、最初の

スクリプトコードにはマイクロタスクがないので、マクロタスクが直接実行されます =>

マクロタスクキュー:

マクロタスクキュー 1

  • タスク1: console.log(1)
  • タスク2: console.log(3)
  • マクロタスクキュー1内のマイクロタスク: console.log(4)
  • マクロタスクキュー 3: マクロタスクキュー 1 内のマクロタスクなので、最後にタスクキューに投入されます。まず、マクロタスクキュー 1 と同じレベルのマクロタスクがあるかどうかを確認します。ある場合は、まず同じレベルのマクロタスクを実行します。ない場合は、マクロタスクキュー 3 を実行できます。それでついに!

マクロタスクキュー 2

コンソール.log(5)

それで、出力は何でしょうか? 6、1、3、4、5、2です!

検証後、結果は正しいです!

js のマクロタスクとマイクロタスクに関するこの記事はこれで終わりです。js のマクロタスクとマイクロタスクに関する関連情報をさらに知りたい場合は、123WORDPRESS.COM で過去の記事を検索するか、以下の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。

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

<<:  Nginx のパフォーマンスを向上させるための提案

>>:  MySQLのファジークエリの要約

推薦する

MySQLデータを復元する2つの方法

1. はじめに少し前、開発者がテスト環境や本番環境で誤った操作をし、データベースを誤って削除/更新し...

DockerはElasticsearch7.6クラスタをインストールし、パスワードを設定します

Elasticsearch 6.8 以降、無料ユーザーは X-Pack のセキュリティ機能を使用でき...

TOM.COMのホームページリニューアルの経験

<br />何の警告もなく、cnBeta で TOM.COM の Web サイトが再設計...

And キーワードを使用した MySQL の複数条件クエリ ステートメント

AND キーワードを使用した MySQL 複数条件クエリ。MySQL では、AND キーワードを使用...

CSSマスクのフルスクリーン中央揃えを実装する方法

具体的なコードは次のとおりです。 <スタイル> #トーストローダーフルスクリーン{ 高さ...

Linux で履歴レコードを表示し、タイムスタンプを追加するためのヒント

Linux で履歴レコードを表示し、タイムスタンプを追加するためのヒントbashに詳しい人なら、hi...

MySQL 8.0 の新機能の分析 - トランザクション データ ディクショナリとアトミック DDL

序文トランザクション データ ディクショナリとアトミック DDL は、MySQL 8.0 で導入され...

MySQLにインデックスを追加しても効果がないいくつかの状況について簡単に説明します。

インデックスを追加すると、クエリの効率が向上します。インデックスを追加するということは、ドキュメント...

LeetCode の SQL 実装 (183. 注文をしたことがない顧客)

[LeetCode] 183.注文しない顧客Web サイトに、Customers テーブルと Or...

Vueのデータ応答性原則の詳細な説明

この記事は主に、Vue のレスポンシブ ソース コードを理解していない、または触れたことがない人向け...

Nodejs 探索: シングルスレッドの高並行性の原理を深く理解する

目次序文一目でわかる建築オペレーティングシステムとの対話シングルスレッドイベント駆動/イベントループ...

React-Dropzone をベースにアップロードコンポーネント機能を開発する (サンプルデモ)

今回はReact-Flaskフレームワーク上でアップロードコンポーネントを開発するスキルについてお話...

Vue での mixin の応用について議論する

Mixin は、再利用可能な機能を Vue コンポーネント間で分散する非常に柔軟な方法を提供します。...

MySQLトランザクションの特徴と分離レベルについてお話ししましょう

インターネットにはすでにこの種の記事が溢れていますが、私がこれをまだ書いている理由は単純です。それは...

mysql data_dirの変更によって発生するエラー問題を解決する

今日は、新しく購入した Alibaba Cloud ECS 環境 (Ubuntu 16.04 LTS...