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 CHARとVARCHARの選択方法

目次VARCHAR 型と CHAR 型結論: VARCHAR 型と CHAR 型VARCHAR と ...

MySQL の DDL と DML についての簡単な説明

目次序文1. DDL 1.1 データベース操作1.2 データテーブルの操作1.3 一般的なデータ型1...

jsとcssのブロッキング問題の詳細な分析

目次DOMContentLoadedとロードjs ブロッキングとは何ですか? CSS ブロッキングと...

MySQL で重複時間を削除して時間差を計算する実装

目次必要:ドライブ:アイデア:成し遂げる:個人的には、実際の開発ではストアド プロシージャの使用はお...

MySQL でテーブルデータをクリアする 2 つの方法とその違い

MySQL でデータを削除するには 2 つの方法があります。切り詰めは大まかな伐採の一種である削除は...

Reactはグローバル箇条書きボックスメソッドをカプセル化します

この記事の例では、Reactカプセル化グローバルポップアップボックスの具体的なコードを参考までに共有...

Linux で docker-compose を使用したソフトウェア構成の詳細な説明

序文この記事では、docker-compose の構成をいくつか紹介します。これらを参考にして、独自...

HTML から PDF への変換事例の概要 (複数の画像を推奨)

仕事の都合上、最近 HTML を PDF に変換する機能について調べることに時間を費やしました。 H...

Docker で Node プロジェクトをビルドしてデプロイする方法

目次DockerとはクライアントサイドDocker基本的なDocker操作画像名画像をプルするその他...

VMWARE で Centos8 仮想マシンをコピーすることによって発生する IP 損失の問題の解決策

VMwareでcentos8サービスをインストールしてコピーすると、次の問題が発生します。 コピー前...

MySQL の大文字と小文字の区別に関する注意

目次MySQLの大文字と小文字の区別はパラメータによって制御されますMySQLの大文字と小文字の区別...

CentOS 7 で MySQL 5.7 をインストールして設定する

この記事では、以下の環境をテストします。 CentOS 7 64 ビット 最小 MySQL 5.7 ...

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

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

HTML テーブル タグ チュートリアル (34): 行スパン属性 ROWSPAN

複雑なテーブル構造では、一部のセルが水平方向に複数のセルにまたがるため、行間属性 ROWSPAN を...

jsBridgeの動作メカニズムを1つの記事で学ぶ

目次js 呼び出しメソッドアンドロイド1.jsはネイティブを呼び出す2. ネイティブコールjs iO...