ホームページ ウェブフロントエンド jsチュートリアル JavaScript はマルチスレッドを実装できますか? JavaScript のタイミングメカニズムについての深い理解_JavaScript スキル

JavaScript はマルチスレッドを実装できますか? JavaScript のタイミングメカニズムについての深い理解_JavaScript スキル

May 16, 2016 pm 06:38 PM
javascript マルチスレッド化

他人の感情を欺きやすい JavaScript タイマー

JavaScript の setTimeout と setInterval は、他人の感情を欺きやすい 2 つのメソッドです。なぜなら、呼び出されると、たとえば、
コードをコピー というコードです。

setTimeout( function(){alert('Hello!'); } , 0);
setInterval( callbackFunction , 100); setTimeout の挨拶メソッドがすぐに実行されることは、何も考えずに述べられているわけではありませんが、JavaScript API ドキュメントでは、2 番目のパラメーターの意味が、コールバック メソッドが実行されるまでのミリ秒数として明確に定義されています。
setInterval の callbackFunction メソッドが 100 ミリ秒ごとに即時に実行されるのと同じです。

ただし、JavaScript アプリケーション開発の経験と同じです。増え続け、充実していくある日、あなたは奇妙なコードを見つけて困惑しました。 解決策:



コードをコピーします 。コードは次のとおりです。 div.onclick = function(){
setTimeout( function(){document.getElementById('inputField').focus();}, 0);
};


0 ミリ秒後に実行されるので、setTimeout は何をしているのでしょうか?
最後までの確固たる信念が揺らぎ始めています。ある日、あなたは誤って悪いコードを書いてしまいました:



コードをコピー コードは次のとおりです: setTimeout( function(){ while(true){} } , 100);
setTimeout( function(){alert(' Hello!'); } , 200);
setInterval( callbackFunction , 200); ;


コードの最初の行は無限ループに入りますが、すぐに 2 行目と 3 行目が期待したものではなく、アラートの挨拶が表示されず、callbacKFunction からのニュースがないことがわかります。

現時点では、あなたはこの状況を受け入れるのが難しいです。長年確立されてきた認識を変えて新しいアイデアを受け入れるプロセスは苦痛を伴うものですが、事実は目の前にあり、JavaScript の真実を探求する必要があります。それは痛みのせいではありません。そして、JavaScript スレッドとタイマーの探索の旅を始めましょう。

雲を開けて月明かりを見てみましょう

上記の誤解の主な理由は次のとおりです。 : 無意識のうちに、JavaScript エンジンは複数のスレッドを実行しており、JavaScript タイマー コールバック関数は非同期で実行されていると信じています。

実際、JavaScript はほとんどの場合、目を欺くためにバックライトを使用する必要があります。事実:

JavaScript エンジンは 1 つのスレッドで実行されます。ブラウザでは JavaScript プログラムを実行するスレッドは常に 1 つだけです。
JavaScript エンジンが 1 つのスレッドで実行されることも意味があります。シングルスレッド シングルスレッド スレッド同期の複雑な問題については心配する必要はありません。問題は単純化されています。

では、シングルスレッドの JavaScript エンジンはどのようにしてブラウザのカーネルと連携してこれらのタイマーを処理し、ブラウザに応答するのでしょうか。
以下はブラウザと組み合わせたものです。

ブラウザのカーネル実装により、複数のスレッドがカーネル制御の下で相互に連携して同期を維持できます。ブラウザ カーネル実装に少なくとも 3 つの常駐スレッド (JavaScript エンジン スレッド、インターフェイス レンダリング スレッド、ブラウザ イベント トリガー スレッド) がある場合、これらの非同期スレッドなど、実行後に終了するスレッドもいくつかあります。以下は、スレッドの JavaScript エンジンが他のスレッドとどのように相互作用し、通信するかを示す図です。ただし、呼び出しの原則は似ています。
図からわかるように、ブラウザーの JavaScript エンジンはイベント駆動型です。ここでのイベントは、ブラウザーによって割り当てられたさまざまなタスクとみなすことができます。これらのタスクは、現在実行されているコード ブロックから発生する可能性があります。 setTimeout を呼び出してタスクを追加するなど、JavaScript エンジンを使用したり、インターフェイス要素のマウス クリック イベント、スケジュールされたトリガー時刻の到着通知、非同期リクエスト ステータス変更通知など、ブラウザ カーネルからの他のスレッドを使用したりできます。 コードの観点から見ると、タスク エンティティはさまざまなコールバック関数であり、JavaScript エンジンはタスク キューにタスクが到着するのを待っています。単一スレッドの関係のため、これらのタスクはキューに入れられ、エンジンによって次々に処理される必要があります。上の図の 🎜>T1-t2..tn はさまざまな時点を表し、tn の下の対応する小さな四角は、ある時点のタスクについて、時刻 t1 であると仮定すると、エンジンは対応するタスク ブロック コードで実行されます。この時点で、ブラウザ カーネル内の他のスレッドのステータスを説明します。
T1 時間:


GUI レンダリング スレッド:


このスレッドは、ブラウザ インターフェイスの HTML 要素をレンダリングする役割を果たします。インターフェイスを再描画する必要がある場合 (再描画)、または何らかの操作によってリフローが発生した場合に、このスレッドが実行されます。ただし、この記事では JavaScript について説明します。タイミング メカニズムについては、この時点でレンダリング スレッドについて説明する必要があります。このスレッドと JavaScript エンジン スレッドは相互に排他的であるためです。これは、JavaScript スクリプトがこれらの要素の属性を変更するときに操作できるため、容易に理解できます。インターフェイスを同時にレンダリングすると、レンダリング スレッドの前後で取得された要素データが不一致になる可能性があります。
JavaScript エンジンがスクリプトを実行している間、ブラウザのレンダリング スレッドは一時停止状態になります。
したがって、ノードの追加、ノードの削除、ノードの外観の変更など、スクリプト内で実行されたインターフェースの更新は、すぐには反映されません。キューにある場合、JavaScript エンジンはアイドル状態のときにレンダリングする機会があります。JS コード ブロックのアラートが発生すると、実際には JS が実行されているのではなく、なぜインターフェイスが更新されるのかという疑問があるかもしれません。


GUI イベント トリガー スレッド:


JavaScript スクリプトの実行は行われません。図からわかるように、t1 期間中にユーザーがマウス ボタンをクリックすると、そのクリックがブラウザのイベント トリガー スレッドによってキャプチャされ、マウス クリック イベントが形成されます。 JavaScript エンジン スレッドでは、このイベントは他のスレッドからタスクに非同期で送信されます。エンジンは t1 でタスクを処理しているため、このマウス クリック イベントは処理を待機しています。 🎜>タイミングトリガースレッド:

ここでのブラウザ モデルのタイミング カウンタは、JavaScript エンジンによってカウントされないことに注意してください。これは、JavaScript エンジンがブロックされたスレッド状態にある場合、時間をカウントすることができないためです。したがって、キュー内のスケジュールされたイベントも非同期イベントです。

図からわかるように、この t1 時間の間、マウス クリック イベントがトリガーされた後、この時点で、以前に設定された setTimeout タイミングも到着します。これは、JavaScript エンジンにとって非常に重要です。たとえば、スケジュールされたトリガー スレッドは、非同期のスケジュールされたイベントを生成し、クリック イベント コールバックの後にキューに入れられます。
同様に、t1 期間内に、次に特定の setInterval がスケジュールされます。間隔のタイミングにより、これら 2 つのイベントがキューに追加されました。

期間 t1 が非常に長い場合、Yuanda は setInterval タイミング間隔に基づいており、タイミング トリガー スレッドは非同期タイミング イベントを継続的に生成することがわかります。ただし、t1 と最初のタイミング イベントの前にあるタスクが処理されると、キュー内のスケジュールされたイベントは中断されることなく順番に実行されます。これは、JavaScript エンジンの場合、処理キュー内の各タスクは同じように処理されますが、

t1 以降、つまり現在処理されているタスクの処理順序が異なるためです。 JavaScript エンジンはタスク キューをチェックし、現在のキューが空ではないことを確認し、t2 で対応するタスクを取り出して実行します。この観点からは、次のようになります。

キューが空でない場合、エンジンはタスクが処理されるまでキューの先頭からタスクを取り出します。つまり、キューに戻った後、エンジンは次のタスクを実行します。その前にキュー内の他のタスクを実行することはできません。タスクは戻ります。
最初のタイマーは無限ループであり、最初のタイマーは 2 番目のタイマーよりも先に文字列を出力します。 >
コードをコピー コードは次のとおりです。
setTimeout(function(){
for( ; ;);
}, 50);


setTimeout(function(){alert('Hello');}, 51);ブラウジングがない場合、サーバーがスクリプトがビジーであることを示すメッセージが表示される前に、2 番目のタイマー アラートは表示されません。単一スレッドの関係のため、最初のタイマー コールバック スクリプトが返されるまで 2 番目のスクリプトは実行されません。
私はあなたを信じます。 これで、JavaScript がマルチスレッド化できるかどうかが明らかになり、JavaScript タイマーの実行メカニズムも理解できました。いくつかのケースを分析してみましょう:

ケース 1: setTimeout と setInterval



コードをコピーします コードは次のとおりです: setTimeout(function(){
/* コード ブロック... */
setTimeout(arguments.callee,
}, 10);

setInterval(){
/*コード ブロック... */
}, 10);


これら 2 つのコードは一緒に見えますが、実際には異なります。最初の段落のコールバック関数の setTimeout は、次の新しい setTimeout タイミングを設定します。 JavaScript エンジンは、次のコールバックが処理されるまで、2 つの setTimeout コールバックの実行時間間隔が 10 ミリ秒以上であると想定されます。 setInterval が設定された後、タイミング トリガー スレッドは 10 秒ごとに非同期タイミング イベントを継続的に生成し、それらをタスク キューの最後に配置します。理論的には、2 つの setInterval コールバック間の実行時間間隔は
ケース 2: 非同期 ajax リクエストは本当に非同期ですか?


多くのクラスメートや友人 JavaScript は単一スレッドで実行されると言われているため、XMLHttpRequest は本当に非同期なのかわかりません。 実際、リクエストは確かに非同期ですが、このリクエストは新しいスレッドリクエストを開くためにブラウザによって行われます(上の図を参照)。コールバックが以前に設定されている場合、リクエストのステータスが変化したときに、非同期スレッドはステータス変更イベントを生成し、それを JavaScript エンジンの処理キューに入れて処理を待機します。タスクが処理されると、JavaScript エンジンは常に単一スレッドでコールバック関数を実行します。具体的には、クリックすると関数セットが実行されます。単一スレッドの onreadystatechange によって。
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

C++ 関数の例外とマルチスレッド: 同時環境でのエラー処理 C++ 関数の例外とマルチスレッド: 同時環境でのエラー処理 May 04, 2024 pm 04:42 PM

C++ での関数例外処理は、マルチスレッド環境でスレッドの安全性とデータの整合性を確保するために特に重要です。 try-catch ステートメントを使用すると、特定の種類の例外が発生したときにそれをキャッチして処理し、プログラムのクラッシュやデータの破損を防ぐことができます。

マルチスレッド環境での JUnit 単体テスト フレームワークの使用 マルチスレッド環境での JUnit 単体テスト フレームワークの使用 Apr 18, 2024 pm 03:12 PM

マルチスレッド環境で JUnit を使用する場合、シングルスレッド テストとマルチスレッド テストという 2 つの一般的なアプローチがあります。シングルスレッド テストは同時実行性の問題を回避するためにメイン スレッドで実行されますが、マルチスレッド テストはワーカー スレッドで実行され、共有リソースが妨げられないように同期されたテスト アプローチが必要です。一般的な使用例には、マルチスレッド環境での JUnit のアプリケーションを反映する、キーと値のペアを格納するための ConcurrentHashMap の使用や、キーと値のペアを操作してその正しさを検証するための同時スレッドなど、マルチスレッド セーフなメソッドのテストが含まれます。 。

Java 関数の同時実行性とマルチスレッド化によってパフォーマンスはどのように向上するのでしょうか? Java 関数の同時実行性とマルチスレッド化によってパフォーマンスはどのように向上するのでしょうか? Apr 26, 2024 pm 04:15 PM

Java 関数を使用した同時実行およびマルチスレッド技術により、次の手順を含むアプリケーションのパフォーマンスを向上させることができます。 同時実行およびマルチスレッドの概念を理解する。 Java の同時実行性と、ExecutorService や Callable などのマルチスレッド ライブラリを活用します。マルチスレッドの行列乗算などのケースを練習して、実行時間を大幅に短縮します。同時実行性とマルチスレッドによってもたらされる、アプリケーションの応答速度の向上と最適化された処理効率の利点をお楽しみください。

PHPでマルチスレッドを実装するにはどうすればよいですか? PHPでマルチスレッドを実装するにはどうすればよいですか? May 06, 2024 pm 09:54 PM

PHP マルチスレッドとは、1 つのプロセスで複数のタスクを同時に実行することを指します。これは、独立して実行されるスレッドを作成することによって実現されます。 PHP の Pthreads 拡張機能を使用して、マルチスレッド動作をシミュレートできます。インストール後、Thread クラスを使用してスレッドを作成および開始できます。たとえば、大量のデータを処理する場合、データを複数のブロックに分割し、対応する数のスレッドを作成して同時処理することで効率を向上させることができます。

マルチスレッド環境では PHP 関数はどのように動作しますか? マルチスレッド環境では PHP 関数はどのように動作しますか? Apr 16, 2024 am 10:48 AM

マルチスレッド環境では、PHP 関数の動作はそのタイプによって異なります。 通常の関数: スレッドセーフで、同時に実行できます。グローバル変数を変更する関数: 安全ではないため、同期メカニズムを使用する必要があります。ファイル操作機能: 安全ではないため、アクセスを調整するには同期メカニズムを使用する必要があります。データベース操作機能: 安全ではないため、競合を防ぐためにデータベース システムのメカニズムを使用する必要があります。

C++ のマルチスレッドで共有リソースを処理するにはどうすればよいですか? C++ のマルチスレッドで共有リソースを処理するにはどうすればよいですか? Jun 03, 2024 am 10:28 AM

ミューテックスは C++ でマルチスレッド共有リソースを処理するために使用されます。std::mutex を通じてミューテックスを作成します。 mtx.lock() を使用してミューテックスを取得し、共有リソースへの排他的アクセスを提供します。ミューテックスを解放するには mtx.unlock() を使用します。

マルチスレッド環境における C++ メモリ管理の課題と対策? マルチスレッド環境における C++ メモリ管理の課題と対策? Jun 05, 2024 pm 01:08 PM

マルチスレッド環境では、C++ メモリ管理はデータ競合、デッドロック、メモリ リークなどの課題に直面します。対策には次のものが含まれます: 1. ミューテックスやアトミック変数などの同期メカニズムの使用、 2. ロックフリーのデータ構造の使用、 4. (オプション) ガベージ コレクションの実装。

C++ でマルチスレッド プログラムをテストするための課題と戦略 C++ でマルチスレッド プログラムをテストするための課題と戦略 May 31, 2024 pm 06:34 PM

マルチスレッド プログラムのテストは、非再現性、同時実行エラー、デッドロック、可視性の欠如などの課題に直面しています。戦略には以下が含まれます。 単体テスト: 各スレッドの単体テストを作成して、スレッドの動作を検証します。マルチスレッド シミュレーション: シミュレーション フレームワークを使用して、スレッド スケジューリングを制御しながらプログラムをテストします。データ競合の検出: valgrind などのツールを使用して、潜在的なデータ競合を見つけます。デバッグ: デバッガー (gdb など) を使用して、ランタイム プログラムのステータスを調べ、データ競合の原因を見つけます。

See all articles