いくつかの面接の質問を使ってJavaScriptの実行メカニズムを調べる

いくつかの面接の質問を使ってJavaScriptの実行メカニズムを調べる

前の単語

JavaScript の動作環境により、単一スレッドとしてロックされ、タスクはキューに入れて実行する必要があります。Web サイトのリソースが大きい場合、これによりブラウザの読み込みが非常に遅くなりますが、実際にはそうではありません。誰もがすぐに同期と非同期を思い浮かべたはずです。

いわゆる同期と非同期もキューイングですが、キューイングする場所が異なります。

同期と非同期

同期タスクはメインスレッドにキューイングされ、非同期タスクはイベントキューにキューイングされます。

同期タスクと非同期タスクは異なるキューに入ります。これは、上で説明したように、異なる場所にキューイングされるということです。

同期タスクはメイン スレッドに入り、非同期タスクはイベント キューに入り、メイン スレッド タスクが実行された後、イベント キューで実行を待機しているタスクは、イベント キュー内のすべてのタスクが実行されるまで、メイン スレッドに入って実行されます。

前菜

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

setTimeout(関数(){
    コンソールログ('b')
}, 200)

setTimeout(関数(){
    コンソールログ('c')
}, 0)

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

アドビ

上から下に向かって、メイン スレッドに入るべきものはメイン スレッドに入り、イベント キューに入るべきものはイベント キューに入ります。

そしてメインスレッドに console.log('a') と console.log('d') があり、タイマー setTimeout によって一定時間実行が遅延されます。名前の通り、非同期タスクはイベントキューに入り、メインスレッドのタスクが実行されるまで待機し、その後メインスレッドに入って実行されます。

遅延が 0 のタイマーは、すぐに実行されるという意味ではなく、メイン スレッドに入り、他のタイマーよりも早く実行されるという意味です。

プレートを追加

(var i = 0; i < 10; i++) {
    setTimeout(関数() {
        コンソールログ(i)
    }, 1000)
}

結果: 10 10

for ループが setTimeout に遭遇するたびに、イベント キューに入れられ、すべてのループが完了するまで実行を待機します。i はグローバル変数です。ループが終了すると、i = 10 になります。setTimeout が再度実行されると、i の値はすでに 10 になっており、結果は 10 個の 10 になります。

var を let に変更します。変数のスコープが異なります。let は現在のループ内で動作するため、イベント キューに入るタイマーの i は毎回異なり、最終的な印刷結果は 0 1 2...9 になります。

マクロタスク マイクロタスク

よく言われる同期タスクと非同期タスクに加え、マクロタスクとマイクロタスクに分けることができます。

メイン マクロ タスク: スクリプト全体 scriptsetTimeoutsetTimeout...

メインのマイクロタスク: promise.then...

実行プロセス:

1. スクリプト全体がマクロタスクとして実行を開始します。

2. マイクロタスクに遭遇したら、それをマイクロタスクキューにプッシュし、マクロタスクをマクロタスクキューにプッシュします。

3. マクロタスクが実行された後、実行可能なマイクロタスクがあるかどうかを確認します。

4. 実行可能なマイクロタスクを見つけ、すべてのマイクロタスクを完了しました

5. 新しいマクロタスクを開始し、すべてのタスクが完了するまで繰り返します。

約束しましょう

const p = 新しい Promise(resolve => {
    コンソールログ('a')
    解決する()
    コンソールログ('b')
})

p.then(() => {
    コンソールログ('c')
})

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

結果: abdc

1. スクリプト全体がマクロタスクキューに入り、実行を開始します。

2. Promiseが作成され、すぐに実行され、abが印刷されます。

3. promise.thenに遭遇し、マイクロタスクキューに入る

4. console.log('d')がdを出力する場合

5. コード全体はマクロ タスクとして実行され、実行可能なマイクロ タスクがあります。マイクロ タスクは実行を開始し、c を出力します。

setTimeout(関数(){
    コンソールログ('setTimeout')
}, 0)

const p = 新しい Promise(resolve => {
    コンソールログ('a')
    解決する()
    コンソールログ('b')
})

p.then(() => {
    コンソールログ('c')
})

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

結果: abdc setTimeout

1.setTimeoutがマクロタスクキューに入る

2. Promiseが作成され、すぐに実行され、abが印刷されます。

3. promise.thenに遭遇し、マイクロタスクキューに入る

4. console.log('d')がdを出力する場合

5. 実行可能なマイクロタスクがあり、cを印刷する

6. マイクロタスクが実行された後、新しいマクロタスクの実行が開始され、setTimeoutの実行が開始され、setTimeoutが印刷されます。

setTimeout(関数(){
    コンソールログ('setTimeout')
}, 0)

const p = 新しい Promise(resolve => {
    コンソールログ('a')
    解決する()
    コンソールログ('b')
})

p.then(() => {
    コンソールログ('c')
    setTimeout(関数(){
        console.log('setTimeout in then')
    }, 0)
})

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

結果: abdc setTimeoutのsetTimeout

1. 上記と同じ

2. cを印刷するマイクロタスクを実行し、setTimeoutに遭遇したときにマクロタスクキューにプッシュします。

3. タイマー遅延時間は同じで、マクロタスクが順番に実行され、setTimeoutthen の setTimeout がそれぞれ出力されます。

タイマーを追加する

コンソールにログ出力します。

新しいPromise(resolve => {
    コンソールログ('b')
    解決する()
}).then(() => {
    コンソールログ('c')
    タイムアウトを設定する(() => {
      コンソールログ('d')
    }, 0)
})

タイムアウトを設定する(() => {
    コンソールログ('e')
    新しいPromise(resolve => {
        コンソールログ('f')
        解決する()
    }).then(() => {
        コンソールログ('g')
    })
}, 100)

タイムアウトを設定する(() => {
    コンソールログ('h')
    新しいPromise(resolve => {
        解決する()
    }).then(() => {
        コンソールログ('i')
    })
    コンソールログ('j')
}, 0)

結果: abchjidefg

1. 印刷する

2.promiseはすぐに実行され、bを出力します。

3.promise.thenはマイクロタスクキューにプッシュします

4.setTimeoutはマクロタスクキューにプッシュします

5. コード全体が実行されると、マイクロタスクが実行を開始し、cを印刷し、setTimeoutに遭遇すると、マクロタスクキューにプッシュされ、実行を待機します。

6. 実行可能なマイクロタスクがない場合、マクロタスクの実行を開始し、タイマーは遅延時間に従って実行のためにキューに入れられます。

7. hj、promiseを印刷し、マイクロタスクキューにプッシュします。

8. 実行可能なマイクロタスク、i を印刷、マクロタスクの実行を続行、d を印刷

9. マクロタスクを100の遅延で実行し、efを印刷し、マイクロタスクを実行してgを印刷すると、すべてのタスクが完了します。

簡単なテスト

コンソールログ('開始')

a().then(() => {
  コンソールログ('a_then')
})

コンソールログ('終了')

関数a() {
  コンソールログ('a_function')
  b() を返します。その後 ((res) => {
    コンソールログ('res', res)
    コンソールログ('b_then')
    return Promise.resolve('メソッド a の戻り値')
  })
}

関数b() {
  コンソールログ('b_function')
  Promise.resolve('戻り値') を返します。
}

結果: start a_function b_function end res return value b_then a_then

上記の例のプロセスに沿って考え、理解を深めてください

要約する

  • JavaScriptはシングルスレッドであり、タスクは実行のためにキューに入れる必要がある
  • 同期タスクはメイン スレッド キューに入り、非同期タスクはイベント キューに入り、実行のためにメイン スレッドにプッシュされるのを待機します。
  • 遅延が 0 の行タイマーは、すぐに実行されるわけではなく、他のタイマーよりも早く実行されます。
  • マクロタスクとマイクロタスクによる js 実行メカニズムをさらに理解する
  • コード全体はマクロタスクとして実行を開始します。実行中、マクロタスクとマイクロタスクは対応するキューに入ります。
  • コード全体の実行が完了したら、マイクロタスクキューに実行待ちのタスクがあるかどうかを確認します。ある場合は、マイクロタスクキューのタスクが完了するまですべてのマイクロタスクを実行します。ない場合は、続行します。
  • 新しいマクロ タスクを実行します。マクロ タスクの実行中にマイクロ タスクが検出されると、そのタスクは実行のためにマイクロ タスク キューにプッシュされます。
  • すべてのタスクが完了するまでこのプロセスを繰り返します。

上記は、いくつかの面接の質問を使用して JavaScript 実行メカニズムの詳細を確認したものです。JavaScript 実行メカニズムの詳細については、123WORDPRESS.COM の他の関連記事に注目してください。

以下もご興味があるかもしれません:
  • JavaScriptイベント実行メカニズムの深い理解
  • JavaScript実行メカニズムの詳細な説明
  • JavaScriptの実行メカニズムを徹底的に理解する
  • JavaScript実行メカニズムの詳細な紹介

<<:  MySQL レプリケーションの利点と原則を詳しく説明します

>>:  opensslを使用して無料の証明書を生成する方法

推薦する

Windows 2008 Server サブドメインを親ドメインに追加すると、ドメインが既に存在するというエラー メッセージが表示されます。

Windows 2008 Serverのサブドメインを親ドメインに参加させると、「ドメインは既に存...

Vue フロントエンドの Excel ファイルのエクスポートの詳細な実装計画

目次1. 技術の選択2. 技術的な実装vue-json-excelプラグインを使用して実装1. vu...

単語のグループ化シーケンスと複数フィールドのグループ化のための MySQL グループ方法

ここで商品テーブルを作成しました。その中のデータを見てみましょう。 mysql> 商品から *...

Linux の一般的なコマンドとショートカット キーの紹介

目次1 システムの紹介2 システムショートカット3 一般的なシステムコマンド1 システムの紹介 1....

https暗号化アクセス用にnginxを設定するための詳細なチュートリアル

環境: 1 CentOS Linux リリース 7.5.1804 (コア)ファイアウォールと sel...

史上最もシンプルな MySQL データのバックアップと復元のチュートリアル (パート 2) (パート 36)

データのバックアップと復元パート2は次のとおりです基本的な概念:バックアップ、現在のデータまたはレコ...

Docker ケース分析: MySQL データベース サービスの構築

目次1 設定ディレクトリとデータディレクトリを作成する3 イメージからホストに構成ファイルをコピーす...

レスポンシブレイアウトの概要(推奨)

レスポンシブレイアウト開発の基礎知識この章は主に以下の部分に分かれています• レスポンシブデザインを...

docker compose の使い方の詳しい説明

目次Docker Compose の使用シナリオ基本的なデモ基本的な操作とメンテナンスdocker-...

HTML 背景画像と背景色_PowerNode Java アカデミー

1. HTML 画像 <img> 1. <img> タグとその src 属性...

MySQL での mysqladmin 日常管理コマンドの概要 (必読)

mysqladmin ツールの使用形式は次のとおりです。 mysqladmin [オプション] コ...

Linux で Nginx ロード バランシングを使用して複数の Tomcat を構成する方法

Linux に nginx と複数の tomcat をインストールする方法はここでは紹介しません。不...

Win7 で IIS7 Web および FTP サービスを完全にアンインストールする方法

昨日、パソコンにPHP開発環境をセットアップした後、Apacheサーバーを再起動するとエラーが続きま...

Vue の vue.$set() メソッドのソースコード例の詳細な説明

Vue を使用してプロジェクトを開発する過程で、次のような問題によく遭遇します。Vue のデータでオ...

Dockerカスタムネットワークの詳細な紹介

目次Dockerカスタムネットワーク1. カスタムネットワークの紹介2. カスタムネットワークを作成...