序文: 仕事でも面接でも、コードの実行順序を知る必要がある場面に遭遇することが多いので、JavaScript の実行メカニズムを徹底的に理解するために時間を費やすつもりです。 JavaScript の実行メカニズムを理解するには、次のことを知っておく必要があります。 (Node 環境とは異なるブラウザ環境を例に挙げます) 1. プロセスとスレッドの概念
コンピュータの中核はすべてのコンピューティング タスクを実行する CPU であり、オペレーティング システムはコンピュータの管理者であり、タスクのスケジュール、リソースの割り当てと管理を担当し、コンピュータのハードウェア全体を制御します。アプリケーションは特定の機能を備えたプログラムであり、プログラムはオペレーティング システム上で実行されることは誰もが知っています。 プロセス: プロセスとは、データセット上で独立した機能を持つプログラムの動的な実行プロセスです。これは、オペレーティングシステムによるリソースの割り当てとスケジュールの独立した単位です。これは、アプリケーションプログラムを実行するためのキャリアです。プロセスは、リソースを所有し、独立して実行できる最小単位であり、プログラム実行の最小単位でもあります。 プロセスの特性:
スレッド: スレッドは、プログラム実行における単一の連続制御フローであり、プログラム実行フローの最小単位であり、プロセッサのスケジューリングとディスパッチの基本単位です。プロセスには 1 つ以上のスレッドがあり、各スレッドはプログラムのメモリ空間 (つまり、プロセスのメモリ空間) を共有します。標準スレッドは、スレッド ID、現在の命令ポインター (PC)、レジスタ、およびスタックで構成されます。プロセスは、メモリ空間 (コード、データ、プロセス空間、開いているファイル) と 1 つ以上のスレッドで構成されます。 プロセスとスレッドの違い:
JS がシングルスレッドなのはなぜですか? たとえば、 JS がマルチスレッドの場合、1 つのスレッドは DOM 要素を変更しようとし、別のスレッドは DOM 要素を削除しようとします。このとき、ブラウザはどちらをリッスンすればよいかわかりません。そのため、複雑さを避けるために、JavaScript は最初からシングルスレッドで設計されました。 HTML5 では、マルチコア CPU の計算能力を活用するために、JavaScript スクリプトで複数のスレッドを作成できる Web Worker 標準を提案しています。ただし、子スレッドはメインスレッドによって完全に制御され、DOM を操作することはできません。したがって、この新しい標準によって、JavaScript がシングルスレッドであるという性質は変わりません。 2. ブラウザの原則フロントエンドエンジニアとしてはブラウザに精通している必要がありますが、ブラウザはマルチプロセスです。 ブラウザのコンポーネント:
ブラウザはどのようなプロセスで構成されていますか? ブラウザプロセス:
サードパーティプラグインのプロセス:
GPU プロセス:
レンダリングプロセス:
レンダリング プロセスにはどのようなスレッドが含まれていますか? GUI レンダリング スレッド:
JavaScript エンジン スレッド:
タイミングトリガースレッド:
イベントトリガースレッド:
非同期リクエストスレッド:
3. 同期と非同期
したがって、JavaScript タスクは一般的に次の 2 つのカテゴリに分類されます。 同期タスク: 同期タスクとは、メイン スレッドで実行するためにキューに入れられたタスクを指します。次のタスクは、前のタスクが完了した後にのみ実行できます。 非同期タスク: 非同期タスクとは、メインスレッドに入らずに「タスクキュー」(イベントキュー)に入るタスクを指します。「タスクキュー」がメインスレッドに非同期タスクが実行可能であることを通知した場合のみ、タスクはメインスレッドに入って実行されます。 一般的な非同期タスク:タイマー、Ajax、イベント バインディング、コールバック関数、
マクロタスクとマイクロタスク: 広範な同期タスクと非同期タスクに加えて、JavaScript にはより洗練されたタスク定義もあります。
タスクの種類によって、タスク キューに入るタスクも異なります。 イベント ループの順序によって、js コードの実行順序が決まります。全体のコード(マクロタスク)を入力すると、最初のループが始まります。次に、すべてのマイクロタスクを実行します。次に、マクロ タスクから再度開始し、完了するタスク キューの 1 つを見つけて、すべてのマイクロ タスクを実行します。 4. 実行スタックとタスクキュー実行スタック: JavaScript コードは実行コンテキストで実行されます。JavaScript には 3 つの実行コンテキストがあります。
一般的に、JS コードには複数のコンテキストがありますが、これらのコンテキストの実行順序はどうなっているでしょうか? スタックは後入れ先出しのデータ構造であることは誰もが知っています。JavaScript の実行スタックはそのようなスタック構造です。JS 関数add(){ コンソール.log(1) 関数foo() コンソール.log(3) } 関数foo(){ コンソール.log(2) } 追加() 上記のコードの実行スタックを見てみましょう。 タスクキュー: 先ほど、 タスク キューは、関連する非同期タスクが実行スタックに入ることができることを示すイベントのキューです。メイン スレッドはタスク キューを読み取り、そこに含まれるイベントを読み取ります。 キューは先入れ先出しのデータ構造です。 前述のように、非同期タスクはマクロタスクとマイクロタスクに分けることができるため、タスク キューもマクロタスク キューとマイクロタスク キューに分けることができます。
5. イベントループ
検証例: それを検証するために質問を見てみましょう (非同期() => { コンソール.log(1) タイムアウトを設定する(() => { コンソールログ('setTimeout1') }, 0); 関数foo(){ 新しい Promise((res,rej) => { を返す コンソール.log(2) 解像度(3) }) } 新しいPromise((resolve,reject)=>{ コンソール.log(4) 解決する() コンソール.log(5) }).then(()=> { コンソールログ('6') }) const res = foo() を待機します。 コンソールログ(res); コンソールログ('7') setTimeout(_ => console.log('setTimeout2')) })()
分析:
6. タイマー
遅延時間を 0 に設定すると、すぐに実行されますか? タイムアウトを設定します(()=>{ コンソール.log(1) },0) コンソール.log(2) しかし、そうではありません。上記の印刷結果では、最初に 2 が印刷され、次に 1 が印刷されます。混乱していると感じますか? 上記のイベント ループのルールを使用すると、非常にわかりやすくなります。グローバル コードが実行され、タイマー setTimeout(fn,0) の意味は、タスクがメインスレッドの最も早い利用可能なアイドル時間に実行されること、つまりできるだけ早く実行されることを指定することです。 「タスク キュー」の最後にイベントを追加するため、同期タスクと「タスク キュー」内の既存のイベントが処理されるまで実行されません。 HTML5 標準では、setTimeout() の 2 番目のパラメータの最小値 (最短間隔) は 4 ミリ秒未満であってはならないと規定されています。この値より小さい場合は、自動的に増加します。以前のバージョンのブラウザでは、最小間隔は 10 ミリ秒に設定されていました。さらに、DOM の変更 (特にページの再レンダリングを伴うもの) は通常、すぐに実行されるのではなく、16 ミリ秒ごとに実行されます。現時点では、 JavaScript 実行メカニズムの詳細な紹介に関するこの記事はこれで終わりです。JavaScript 実行メカニズムに関するより関連性の高いコンテンツについては、123WORDPRESS.COM の以前の記事を検索するか、以下の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。 以下もご興味があるかもしれません:
|
<<: CSS で text-align と margin: 0 auto を使用して中央に配置する例コード
>>: Nginx がサーバーの生存状態をパッシブにチェックする詳細な説明
時間は本当に存在するのでしょうか?時間は人間が考え出した概念に過ぎず、物事の変化を測る基準に過ぎない...
新年の初めに、友人の健康と2013年が素晴らしい年となることを心からお祈りいたします。この記事では、...
Hexo は Windows 10 でカスタムドメイン名を GitHub にバインドしますまずドメイ...
怖いですね! 写真の翻訳: (内側から外側へ)最初のレイヤー:ユーザーエクスペリエンス第2層:コンテ...
1. まず、移行サーバー上のデータ ファイルを見つけます。MySQL 5.7 とデフォルトのインスト...
MySQL データベースの増分バックアップを実行するには、データベース構成ファイル /etc/my....
目次1. MySQLをダウンロードする1.1 ダウンロード1.2 インストール1. MySQLをダウ...
区切り文字なしの文字列抽出質問の要件データベース内のフィールド値:実装効果: 1行のデータを複数行に...
アプリケーションが牛のように遅い理由は数多くあります。ネットワーク、システム アーキテクチャ、または...
問題コードuseEffectによって発生したクロージャの問題コードを見てみましょう 定数 btn =...
目次1. Props 親コンポーネント ---> 子コンポーネント通信2. $emit 子コン...
WeChatコンポーネントの形式で提供されます。コンポーネント内部ではasync/awaitが使用さ...
背景フレックス レイアウトにより、配置とスペースの割り当てがより効果的に実現されます。最近、flex...
ul liの前のアイコン1をキャンセルしますクリア値1値を1に設定ラベル中央値1をクリアラベルの中央...
目次スプレッド演算子を使用してプロパティを渡すのは避けてください関数パラメータをオブジェクトにカプセ...