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のファジークエリの要約

推薦する

Vue の双方向イベントバインディング v-model の原理についての簡単な説明

目次説明する:要約する補充するDOM を直接変更して操作する js や jQuery とは異なり、V...

Expressはログイン認証を実装

この記事では、ログイン認証を実装するためのExpressの具体的なコードを例として紹介します。具体的...

Docker+Selenium Grid に基づく技術アプリケーションをテストするためのサンプル コード

Selenium Grid の紹介Selenium Grid のいくつかの新しい機能は、今後リリース...

Vueの子コンポーネントが親コンポーネントのメソッドを呼び出す場合の詳細な説明

1. 子コンポーネントのthis.$parent.eventを通じて親コンポーネントメソッドを直接呼...

React は入力値を取得し、2 つのメソッドの例を送信します

方法1: DOMが提供するイベントオブジェクトのターゲットイベント属性を使用して値を取得し、送信する...

Docker Nginxコンテナの制作と展開の実装方法

クイックスタート1. Docker Hubでnginxイメージを見つけるdocker 検索 ngin...

ActiveMQ メッセージ サービスを構築するための Docker 学習方法の手順

序文ActiveMQ は、Apache が開発した最も人気があり強力なオープン ソース メッセージ ...

MySQLdump コマンドを使用した MySQL データの移行

このソリューションの利点はシンプルさと使いやすさですが、欠点はダウンタイムが長くなることです。 した...

CSS ウェイト値(カスケード)の例の詳細な説明

•CSSには多くのセレクターがあります。複数のセレクターを同じ要素に適用するとどうなるでしょうか? ...

Vue のディスパッチとブロードキャストの自己実装の詳細説明 (ディスパッチとブロードキャスト)

解決すべき問題主にコンポーネント間のクロスレベル通信用なぜディスパッチとブロードキャストを自分で実装...

Windows 10 での MySQL 8.0.19 のインストールと設定のチュートリアル

来学期にMySQLを勉強します。事前に自宅で練習していませんでした。インストールに時間がかかるとは思...

nginx を使用したプロキシ サーバーの設定

Nginx は、リバース プロキシ機能を使用して負荷分散を実装できるほか、フォワード プロキシ機能を...

Docker Consul コンテナ サービスの更新と見つかった問題の概要

目次1. コンテナサービスの更新とDockerコンサルの検出1. サービス登録と検出とは何ですか? ...

CSS でマウスの位置をマッピングし、マウスを動かしてページ要素を制御する (サンプル コード)

マウスの位置をマッピングしたり、ドラッグ効果を実装したりすることは、 JavaScriptで行うこと...

VueはWebSocketを使用してチャット機能をシミュレートします

この効果は、2つのブラウザが互いにシミュレートしていることを示しています 1. シミュレートされたノ...