この記事では、JavaScript シングルスレッドに関する知識を提供します。JavaScript はシングルスレッド言語です。なぜ JavaScript はタイマーと関数を同時に実行できるのでしょうか? 皆様のお役に立てれば幸いです。
#1. プロセスとスレッド
1.1 プロセス
は、特定のデータ セット上でコンピュータ内のプログラムを実行するアクティビティであり、システム内のリソース割り当てとスケジューリングの基本単位であり、オペレーティング システム構造の基礎です。スレッド用に設計された現代のコンピューター アーキテクチャでは、プロセスはスレッドのコンテナーです。プログラムは命令、データ、およびそれらの構成の記述であり、プロセスはプログラムの実体です。これは、コンピュータ内で特定のデータセットに基づいてプログラムを実行するアクティビティであり、システム内のリソース割り当てとスケジューリングの基本単位であり、オペレーティング システム構造の基礎です。プログラムは命令、データ、およびそれらの構成の記述であり、プロセスはプログラムの実体です。 ここでのプロセスを工場現場と比較します。これは、CPU が処理できる単一のタスクを表します。 CPU は常に 1 つのプロセスを実行しており、他のプロセスは非実行状態になります。1.2 スレッド (スレッド)
は、オペレーティング システムが操作のスケジューリングを実行できる最小単位です。これはプロセスに含まれており、プロセス内の実際の操作単位となります。スレッドとは、プロセス内の単一の順次制御フローを指します。プロセス内で複数のスレッドを同時に実行でき、各スレッドは異なるタスクを並行して実行します。 ここでは、スレッドをワークショップのワーカーに例えています。つまり、ワークショップでは、複数のワーカーが協力してタスクを完了できます。2. マルチスレッド ブラウザ
ブラウザ カーネルはマルチスレッドであり、カーネルの制御下で、各スレッドが相互に連携して同期を維持します。通常、ブラウザは次の常駐スレッド構成で構成されます:JS エンジンはマルチスレッドです。シングルスレッドとは、JS エンジンが JS を実行するときに、実行用のスレッドを 1 つだけ割り当てることを意味します。これは、JS エンジンが JavaScript の実行用にスレッドを割り当てることを意味します。シングルスレッド呼び出し。
2.1 ここで JS の実行メカニズムについて話しましょうJavaScript はシングルスレッドであるため (タブ ページで JavaScript プログラムを実行する JS スレッドは 1 つだけです)いつでも) 。 したがって、JavaScript コードを実行するにはタスク キューに依存する必要があります。
JS エンジンは常にタスク キューにタスクが到着するのを待ってから、タスクを実行します。
もちろん、この方法で同期タスクを実行しても問題はありません。タスクをタスクキューに入れて 1 つずつ実行します。ロジックは非常に明確です。しかし、バックグラウンドにリクエストを送信すると、送信してから受信するまでに 1 秒かかる場合があります。1 秒も待つことはできません。5 回リクエストしたら、5 秒待つのですか?表示はニーズを満たしていないため、この問題を処理するには非同期タスクが必要です。
2.2 同期タスクと非同期タスク同期タスクとは、メイン スレッドでの実行のためにキューに入れられたタスクを指します。前のタスクが完了した場合にのみ、次のタスクを続行できます。 Web サイトを開いたとき、要素のレンダリングなどの Web サイトのレンダリング プロセスは、実際には同期タスクです。非同期タスクとは、メイン スレッドには入らず、タスク キューに入るタスクを指します。 . タスクキューのみがメインスレッドに通知し、非同期タスクが実行できる場合にのみタスクがメインスレッドに入ります. Webサイトを開いたときの画像や音楽の読み込みは、実際には非同期タスクです。
皆さんは、イベント ループについて比較的具体的に理解している必要があります。ここでは詳しく説明しません。理解できない場合は、後で説明しますので、教えてください。
3. この記事は重要なポイントに焦点を当てています - 直接読むことができますしかし、タスク キューについて何か質問はありますか?これは物体ですか?配列ですか?私のロジックによれば、JavaScript メイン スレッドは同期関数を実行し、非同期関数はタスク キューに配置できます。このタスク キューはオブジェクトにすることができます。同期タスクの実行が終了したら、このオブジェクト (タスク キュー) をメイン スレッドにプッシュします。スレッド内では問題ありませんが、私が思っていたものと違いました。 Evnet Loop のタスク キューは、ブラウザのイベント トリガー スレッドに配置されます。JS エンジンが非同期関数を実行すると、非同期タスクはイベント トリガー スレッドに配置されます。対応する非同期タスクが一致すると、イベント トリガー スレッドに配置されます。トリガー条件 トリガーされると、イベント トリガー スレッドは、JS エンジンのメイン スレッドのキューの最後に非同期タスクを追加し、実行を待機します。
これは私たちが想像していたシングルスレッドの JavaScript とは異なりますか?まあ、実際には同じではないので、最終的な結論は、私たちが話しているタスクキューは実際にはスレッドであるということです。
次に、最初に説明したタイマーに戻りますが、基本的には誰もが推測できるように、タイマー スレッドによって制御されます。
JavaScript はシングルスレッドであるため、スレッドがブロックされた状態になるとタイミングの精度に影響するため、タイミングのために別のスレッドを開く必要があります。
setTimeout または setInterval を使用する場合、タイマー スレッドで時間を計測する必要があり、時間が完了すると、特定のイベントがイベント キューにプッシュされます。
4. 結論
したがって、JavaScript はシングルスレッドであると言うのは正しいことです。たとえ王様が来ても、それもシングルスレッドですが、私たちのイベント ループとタイマーは別のスレッドに配置されます。
5. V8 エンジン - 拡張機能
V8 エンジンは JavaScript エンジンの実装です。元々は言語専門家によって設計され、後に Google に買収されました。オープンソースです。 。
V8 は C を使用して開発されています。JavaScript を実行する前に、JavaScript をバイトコードに変換したり、実行のために解釈したりする他の JavaScript エンジンと比較して、V8 はそれをネイティブ マシン コード (IA-32、x86-64、ARM、または MIPS CPU)を使用し、インライン キャッシュなどの方法を使用してパフォーマンスを向上させます。
これらの機能により、JavaScript プログラムは V8 エンジンの下でバイナリ プログラムと同じ速度で実行されます。 V8 は、Windows、Linux、Android などの多くのオペレーティング システムをサポートし、IA32、X64、ARM などの他のハードウェア アーキテクチャもサポートし、優れた移植性とクロスプラットフォーム機能を備えています。
5.1 ワークフロー
V8 エンジンには、JavaScript の実行プロセスに、コンパイルと実行という 2 つの主要な段階があります。これは、実行前の C の完全なコンパイルとは異なります。ユーザーが使用するときにコンパイルして実行する必要があります。 V8 では、JavaScript 関連のコードは一度にすべてコンパイルされるのではなく、特定のコードを実行する必要があるときにコンパイルされるため、応答時間が短縮され、時間のオーバーヘッドが削減されます。 V8 エンジンでは、ソース コードはまずパーサーによって抽象構文ツリー (AST) に変換され、次に JIT コンパイラーの完全なコード ジェネレーターを使用して AST からローカル実行可能コードが直接生成されます。このプロセスは、AST からバイトコードへの変換時間を短縮し、コードの実行速度を向上させる、JAVA の第 1 世代のバイトコードまたは中間表現とは異なります。ただし、バイトコードへの変換の中間プロセスがないため、コードを最適化する機会は減少します。
ローカル コードのコンパイル時に V8 エンジンによって使用される主なクラスは次のとおりです。
スクリプト: ソース コードとコンパイル後に生成されるローカル コードを含む JavaScript コードを表します。コンパイルの入り口と実行の入り口の両方です;
Compiler: コンパイラー クラス、補助グループ コードをコンパイルして生成するスクリプト クラス、インタプリタ (パーサー) を呼び出して AST と完全なコード ジェネレーターを生成します。 、AST をローカル コードに変換します;
AstNode: 他のすべてのノードの基本クラスである抽象構文ツリー ノード クラスには、多くのサブクラスが含まれており、生成されるさまざまなサブクラスについては後で説明します。さまざまなローカル コード;
AstVisitor: 抽象構文ツリーのビジター クラス、主に異種の抽象構文ツリーを走査するために使用されます;
FullCodeGenerator: サブクラスAST を走査することによって JavaScript のローカル実行可能コードを生成する AstVisitor クラスの。
JavaScript コードのコンパイル プロセスは、大まかに次のとおりです。Script クラスは、Compiler クラスの Compile 関数を呼び出して、そのローカル コードを生成します。 Compile 関数は、まず Parser クラスを使用して AST を生成し、次に FullCodeGenerator クラスを使用してローカル コードを生成します。ネイティブ コードは特定のハードウェア プラットフォームと密接に関連しており、FullCodeGenerator は複数のバックエンドを使用して、プラットフォームに一致するネイティブ アセンブリ コードを生成します。 FullCodeGenerator は AST を走査することによって各ノードに対応するアセンブリ コードを生成するため、グローバル ビューが欠落しており、ノード間の最適化は問題外です。
[関連する推奨事項: JavaScript 学習チュートリアル ]
以上がJavaScript のシングルスレッドを本当に理解していますか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。