いくつかの面接の質問を使って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を使用して無料の証明書を生成する方法

推薦する

HTML の基本 - CSS スタイルシート、スタイル属性、フォーマット、レイアウトの詳細

1.位置:固定一部の Web サイトの右下隅にあるポップアップ ウィンドウなどの、ブラウザーを基準と...

Vant Uploaderは1枚以上の写真をアップロードするコンポーネントを実装します

この記事では、1枚以上の写真をアップロードするためのVant Uploaderコンポーネントを紹介し...

CSSでできるならJavaScriptは使わない

序文JavaScript で記述できるアプリケーションは、最終的には JavaScript で記述さ...

MySQLのデッドロックチェック処理の通常の方法

通常、デッドロックが発生すると、重みが最も小さい接続が強制終了され、ロールバックされます。ただし、最...

React useEffect の理解と使用

目次繰り返しレンダリングループを避ける副作用の除去についてReact16.8 の新しい useEff...

Nginx と GeoIP モジュールを使用して IP の地域情報を読み取る方法

LinuxにGeoIPをインストールする yum で nginx-module-geoip をインス...

node.js で Web サーバーを作成する手順の詳細な説明

序文node.js でサーバーを作成するのは非常に簡単です。小さいながらも完全な Web サーバーを...

Linux システムで Vim を使用してリモート ファイルを読み書きするコマンドの詳細な説明

vim の動作モードを設定する (一時的) :set (モード情報) :set nu — 行番号を表...

CentOS8 Linux 8.0.1905 のインストール手順(図解)

現在、CentOS の最新バージョンは CentOS 8 です。次に、CentOS Linux 8....

MySQL の 4 つのトランザクション分離レベルを例を使って分析する

序文データベース操作では、同時データ読み取りの正確性を効果的に保証するために、トランザクション分離レ...

航空機戦争ゲームを実装するためのJavaScript

この記事では、キャンバスとjsを使用して簡単な飛行機戦争を実装する方法を参考までに紹介します。具体的...

CSS を使用して適応型の幅と高さを持つ 16:9 の長方形を実装する例

先ほど、適応幅と高さが1:1の正方形を作成する方法について説明しました。 https://www.j...

jQueryはシャトルボックス効果を実現します

この記事では、シャトルボックス効果を実現するためのjQueryの具体的なコードを参考までに紹介します...

Mysql5.7でのスケジュールバックアップの実装

1. MySQL インストール パス D:\xxx\MYSQL\MySQL Workbench CE...

Linux ディスクとディスク パーティションを理解するための記事

序文Linux システムのすべてのハードウェア デバイスは、ファイルの形式で表現され、使用されます。...