JavaScriptのマルチスレッド
わかりました、始める前に、きれいになって、この記事のタイトルが少しセンセーショナルなことを認めましょう! JavaScriptにはマルチスレッド機能が実際にはなく、JavaScriptプログラマーがそれを変更することができることは何もありません。すべてのブラウザで - Google Chromeを除いて - JavaScriptは単一の実行スレッドで実行されます。
しかし、私たちにできることは、マルチスレッド環境の利点の1つを引き起こす限り、マルチスレッドをシミュレートします。これは、それ以外の場合はブラウザをフリーズアップし、Firefoxでそれらの「反応しないスクリプト」警告の1つを生成するコードです。 キーテイクアウト
javaScriptはマルチスレッドをネイティブにサポートするのではなく、非同期タイマーとWebワーカーを通じてそれをシミュレートし、ブラウザを凍らせずに集中的な計算を許可します。
非同期タイマーはタスクをより小さなチャンクに分解し、コードが時間の経過とともに実行する方法を管理することでブラウザが反応しなくなるのを防ぎます。- Webワーカーは、ユーザーインターフェイスに影響を与えることなくバックグラウンドタスクを実行するJavaScriptの機能を強化しますが、DOMと対話したり、特定のWeb APIを使用したりすることはできません。
ブラウザをロックするリスクのある複雑な操作の場合、コードをリファクタリングして非同期タイマーを使用すると、UIフリーズを防ぎ、リソース集約型プロセスをより効果的に管理できます。
- JavaScriptの単一スレッド性にもかかわらず、非同期プログラミングやWebワーカーなどの技術は、マルチスレッドのようなシナリオを処理するための堅牢なツールを開発者に提供し、集中的なタスクのパフォーマンスを向上させます。
- 時間は誰も待っていません
- それはすべて、非同期タイマーの使用にかかっています。非同期タイマー内で繰り返しコードを実行すると、ブラウザのスクリプトインタープリターの時間に各反復を処理する時間を与えています。 効果的に、Iteratorの内部のコードは、通訳者にすべてをすぐに実行するよう求めています。ただし、非同期タイマー内の同じコードは、コードを小さく控えめなチャンクに分割しています。つまり、「このコードを可能な限り速く実行する」 - 待ってから、「できるだけ速くこのコードを実行する」など、
- n
- トリックは、各反復内のコードが小さく、インタープリターがタイマーの速度内で完全に処理するのに十分なほど単純であることです。その要件が満たされている場合、コード全体がどれほど激しいかは関係ありません。なぜなら、一度に実行するように要求していないからです。
「強すぎる」どれだけ強烈ですか?
通常、私が集中的すぎることが証明されたスクリプトを書いている場合、私はそれを再設計することを見ています。このような重要な減速は、通常、コードの問題、またはアプリケーションの設計に関するより深い問題を示しています。
しかし、時にはそうではありません。時々、特定の操作の強度を避ける方法がありません。
それは、特定のケースで最良の解決策かもしれません。おそらく、アプリケーションの一部の処理はサーバー側に移動する必要があります。そこでは、一般的に、そして一般的にスレッドされた実行環境(Webサーバー)を使用するためのより多くの処理能力があります。しかし、最終的には、それがオプションではない状況を見つけるかもしれません。javaScriptが単に
何かをすることができなければならないか、気の毒に思う必要があります。それは、私のFirefox拡張機能、Dust-Meセレクターを開発するときに私が見つけた状況です。 その拡張機能のコアは、ページに適用されるCSSセレクターをテストし、実際に使用されているかどうかを確認する機能です。これの本質は、Dean Edwards 'Base2:のMatchall()メソッドを使用した一連の評価です。
確かに、十分に簡単です。しかし、Matchall()自体は、CSS1またはCSS2セレクターを解析して評価し、Matchを探してDOMツリー全体を歩きます。拡張機能は、個々のセレクター
に対してそれを行います。そのプロセスは、表面上で非常に単純で、ブラウザ全体が発生中にフリーズするほど集中的になる可能性があります。そして、これが私たちが見つけたものです。for(var i=0; i<selectors.length; i++) <br> { <br> if(base2.DOM.Document.matchAll <br> (contentdoc, selectors[i]).length > 0) <br> { <br> used ++; <br> } <br> else <br> { <br> unused ++; <br> } <br> }
ログイン後にコピーログイン後にコピーログイン後にコピーログイン後にコピーブラウザをロックすることは明らかにオプションではないので、これが機能する場合は、エラーなしで実行する方法を見つけなければなりません。 簡単なテストケース
2つのレベルの反復を含む簡単なテストケースで問題を示しましょう。内部レベルは意図的に集中的すぎるため、レース条件を作成できますが、外側のレベルはかなり短いため、メインコードをシミュレートできます。これが私たちが持っているものです:
次に、そのコードをFirefoxで実行しましょう(この場合、2GHz MacBookのFirefox 3)...予想通り、ブラウザのUIが実行中にフリーズします(たとえば、プロセスを更新して放棄することは不可能になります) 。約90回の反復後、Firefoxは「反応しないスクリプト」警告ダイアログを作成します。function process() <br> { <br> var above = 0, below = 0; <br> for(var i=0; i<200000; i++) <br> { <br> if(Math.random() * 2 > 1) <br> { <br> above ++; <br> } <br> else <br> { <br> below ++; <br> } <br> } <br> } <br> <br> <br> function test1() <br> { <br> var result1 = document.getElementById('result1'); <br> <br> var start = new Date().getTime(); <br> <br> for(var i=0; i<200; i++) <br> { <br> result1.value = 'time=' + <br> (new Date().getTime() - start) + ' [i=' + i + ']'; <br> <br> process(); <br> } <br> <br> result1.value = 'time=' + <br> (new Date().getTime() - start) + ' [done]'; <br> }
ログイン後にコピーログイン後にコピーログイン後にコピー<form action=""> <br> <fieldset> <br> <input type="button" value="test1" onclick="test1()" /> <br> <input type="text" /> <br> </fieldset> <br> </form> <br>
ログイン後にコピーログイン後にコピーそれを許可する場合、さらに90回の反復後、Firefoxが同じダイアログを再び生成します。この点で、Safari 3とInternet Explorer 6が同様に動作し、凍結したUIと警告ダイアログが作成されるしきい値で動作します。 Operaでは、そのようなダイアログはありません。コードが完了するまでコードを実行し続けていますが、ブラウザUIはタスクが完了するまで同様に冷凍されます。
明らかに、実際にはそのようなコードを実行することはできません。それでは、それを再要素して、アウターループに非同期タイマーを使用しましょう:
for(var i=0; i<selectors.length; i++) <br> { <br> if(base2.DOM.Document.matchAll <br> (contentdoc, selectors[i]).length > 0) <br> { <br> used ++; <br> } <br> else <br> { <br> unused ++; <br> } <br> }
ログイン後にコピーログイン後にコピーログイン後にコピーログイン後にコピーテストページを表示します
(忙しいフラグは、タイマーインスタンスが衝突するのを防ぐために使用されます。次の反復が来るときにサブプロセスの真ん中にいる場合は、次の反復を待つだけで、1つだけを保証するだけです。サブプロセスは一度に実行されています。)内側
プロセスでできる作業はまだ最小限ですが、そのプロセスを実行できます。外側のループは基本的に永遠に、ブラウザは決してフリーズしません。 それはそれに似ています - 私たちはこれを野生で使用できます。
あなたは狂っています!
私はすでに反対者を聞くことができます。実際、私は自分自身になることができます。なぜあなたはこれをするのですか?どのような狂った人がJavaScriptをこれらすべての場所に押し進めることを主張することを主張します。あなたのコードはあまりにも激しいです。これは仕事の間違ったツールです。これらの種類のフープを飛び越えなければならない場合、アプリケーションの設計は根本的に間違っています。
既に、重いスクリプトが仕事をする方法を見つけなければならなかった1つの例について言及しました。それは、または全体のアイデアを放棄しなければならなかったかのいずれかでした。あなたがその答えに確信していない場合、記事の残りの部分もあなたにアピールしないかもしれません。しかし、あなたがいる場合、または少なくとも、あなたが確信を持つことを受け入れている場合は、実際にそれを家に釘付けにする別の例があります:JavaScriptを使用してコンピューターと対戦できるゲームを書くことができます。
ゲーム
ここで私が話しているのは、ゲームのルールを理解するために必要なコードです。その後、そのゲームであなたを打ち負かすために状況と戦術を評価できます。複雑なもの。
要約すると、隣接する形状と色の一致によってボード全体に進みます。たとえば、たとえば緑色の三角形を開始すると、他の三角形、または他の緑の形状に移動できます。あなたの目的は、中央のクリスタルに到達し、それをボードの反対側に持って行くことです。相手は同じことをしようとします。相手からクリスタルを盗むこともできます したがって、動きを決定する論理的ルールがあり、戦術が出現することもあります。たとえば、相手にクリスタルに到達させたり、クリスタルを盗んだりすることを避けるために、ブロックする動きを選択したり、到達できない場所で終了しようとします。コンピューターの作業は、特定の状況に最適な動きを見つけることです。そのため、そのプロセスを要約の擬似コードに見てみましょう。
戦術を評価します。それが私たちに良い動きを与えた場合、私たちは完了です。それ以外の場合は、別の戦術を評価するか、動きがあるか、それがなくても合格しなければならないと結論付けるまで評価します。
これらの戦術関数のそれぞれは、ボード上のすべての位置と、潜在的な将来の位置を評価する必要があるため、それぞれさまざまな要因に照らして何度も潜在的な将来の位置を評価する必要があるため、高価なプロセスを実行します。この例には3つの戦術しかありませんが、実際のゲームでは、数十の異なる可能性があり、それぞれが評価するのに費用がかかります。これらの評価のいずれかが個別に問題ありませんが、それらすべてが連続して実行され、ブラウザをフリーズする過度に激しいプロセスを作成します。for(var i=0; i<selectors.length; i++) <br> { <br> if(base2.DOM.Document.matchAll <br> (contentdoc, selectors[i]).length > 0) <br> { <br> used ++; <br> } <br> else <br> { <br> unused ++; <br> } <br> }
ログイン後にコピーログイン後にコピーログイン後にコピーログイン後にコピーでは、メインコードを控えめなコード
タスクに分割することでしたしかし、ここでやろうとしているのは、天井のない実行環境、つまり複雑さと長さの点で上限のないプロセスを作成することです。そして、それが私たちがやったことです。 このパターンは、数百または数千のタスクで、無期限に
無期限に拡張できます。実行するのに長い時間がかかるかもしれませんが、実行するには実行されます。各個々のタスクがそれほど激しくない限り、ブラウザを殺さずに実行されます。function process() <br> { <br> var above = 0, below = 0; <br> for(var i=0; i<200000; i++) <br> { <br> if(Math.random() * 2 > 1) <br> { <br> above ++; <br> } <br> else <br> { <br> below ++; <br> } <br> } <br> } <br> <br> <br> function test1() <br> { <br> var result1 = document.getElementById('result1'); <br> <br> var start = new Date().getTime(); <br> <br> for(var i=0; i<200; i++) <br> { <br> result1.value = 'time=' + <br> (new Date().getTime() - start) + ' [i=' + i + ']'; <br> <br> process(); <br> } <br> <br> result1.value = 'time=' + <br> (new Date().getTime() - start) + ' [done]'; <br> }
ログイン後にコピーログイン後にコピーログイン後にコピーreturnのパス
このアプローチの強さも主要な弱点です。内的関数は非同期であるため、外部関数から値を返すことはできません。したがって、たとえば、私たちはこれを行うことはできません(またはむしろ、できますが、意味はありません):
CheckSomThines()関数は、内部関数が非同期であるため、常にfalseを返します。外部関数は、内部関数の最初の反復が起こる前に戻ります!for(var i=0; i<selectors.length; i++) <br> { <br> if(base2.DOM.Document.matchAll <br> (contentdoc, selectors[i]).length > 0) <br> { <br> used ++; <br> } <br> else <br> { <br> unused ++; <br> } <br> }
ログイン後にコピーログイン後にコピーログイン後にコピーログイン後にコピーこの次の例は、同様に無意味です:
外部関数の範囲外であるため、そこから戻ることはできません。その返品値は、エーテルに役に立たなく消えます。
ここでできることは、ajaxコーディング技術から葉を取り出して、コールバック関数を使用します(この例では「oncomplete」と呼んでいます):function process() <br> { <br> var above = 0, below = 0; <br> for(var i=0; i<200000; i++) <br> { <br> if(Math.random() * 2 > 1) <br> { <br> above ++; <br> } <br> else <br> { <br> below ++; <br> } <br> } <br> } <br> <br> <br> function test1() <br> { <br> var result1 = document.getElementById('result1'); <br> <br> var start = new Date().getTime(); <br> <br> for(var i=0; i<200; i++) <br> { <br> result1.value = 'time=' + <br> (new Date().getTime() - start) + ' [i=' + i + ']'; <br> <br> process(); <br> } <br> <br> result1.value = 'time=' + <br> (new Date().getTime() - start) + ' [done]'; <br> }
ログイン後にコピーログイン後にコピーログイン後にコピーしたがって、checksomhings()を呼び出すと、匿名関数をその引数として渡します。ジョブが完了したときにその関数は最終値で呼び出されます。 エレガント?いいえ。しかし、堅牢に機能しますか?はい。そして、それがポイントです。この手法を使用して、そうでなければ不可能なスクリプトを書くことができます。
Androidsはシリコン羊の夢を夢見ていますか?<form action=""> <br> <fieldset> <br> <input type="button" value="test1" onclick="test1()" /> <br> <input type="text" /> <br> </fieldset> <br> </form> <br>
ログイン後にコピーログイン後にコピーこのテクニックには、キットにあるため、以前は可能性の領域から抜け出したJavaScriptプロジェクトに取り組む手段があります。私がこのパターンを開発したゲームにはかなり単純なロジックがあり、したがってかなり単純な
脳がありますが、従来の反復にはまだ多すぎました。そして、もっと多くの影響力が必要な他のゲームがたくさんあります!function test2() <br> { <br> var result2 = document.getElementById('result2'); <br> <br> var start = new Date().getTime(); <br> <br> var i = 0, limit = 200, busy = false; <br> var processor = setInterval(function() <br> { <br> if(!busy) <br> { <br> busy = true; <br> <br> result2.value = 'time=' + <br> (new Date().getTime() - start) + ' [i=' + i + ']'; <br> <br> process(); <br> <br> if(++i == limit) <br> { <br> clearInterval(processor); <br> <br> result2.value = 'time=' + <br> (new Date().getTime() - start) + ' [done]'; <br> } <br> <br> busy = false; <br> } <br> <br> }, 100); <br> <br> }
ログイン後にコピーこのようなトリックをやってのけることができれば、誰が何が可能かを言うのは誰ですか?自然言語処理、ヒューリスティック…おそらく、JavaScriptで人工知能を開発するためのビルディングブロックがあります!この投稿を読んで楽しんだなら、学習できるのが大好きです。マスターから新鮮なスキルとテクニックを学ぶ場所。メンバーは、Web用のJavaScriptプログラミングなど、SitePointのすべての電子ブックやインタラクティブなオンラインコースに即座にアクセスできます。 この記事へのコメントは閉じられています。 JavaScriptについて質問がありますか?フォーラムで聞いてみませんか? 画像クレジット:ランデンLピーターソン javascriptのマルチスレッドに関するよくある質問
JavaScriptマルチスレッドにおけるWebワーカーの役割は何ですか?
Webワーカーは、JavaScriptマルチスレッドで重要な役割を果たします。これらは、Webコンテンツがバックグラウンドスレッドでスクリプトを実行する簡単な手段です。ワーカースレッドは、ユーザーインターフェイスに干渉することなくタスクを実行できます。さらに、xmlhttprequestを使用してI/Oを実行できます(ただし、ResponseXMLおよびチャネル属性は常にnullです)。作成されたら、ワーカーは、そのコードで指定されたイベントハンドラーにメッセージを投稿することによって作成されたJavaScriptコードにメッセージを送信できます(およびその逆)。 🎜>
JavaScriptは本質的にシングルスレッドですが、非同期コールバックと約束を使用してマルチスレッドを処理できます。つまり、JavaScript自体は単一のスレッドで動作しますが、将来実行するタスクをスケジュールし、効果的に複数のタスクを同時に実行できるようにすることを意味します。これは、メインスレッドが他のコードを実行し続けている間にバックグラウンドで処理できるユーザー入力やAPIリクエストなどの操作を処理するのに特に便利です。 🎜> JavaScriptのマルチスレッドはWebワーカーを通じて達成できますが、これらの労働者はDOMまたは他のWeb APIにアクセスできないことに注意することが重要です。それらは、メインスレッドに前後に送信できるデータ型のみに限定されています。また、各ワーカーは個別のインスタンスであるため、範囲やグローバル変数を共有しません。 「クラスター」と呼ばれるモジュールでは、メインノードプロセス(マスター)とサーバーポートを共有する子プロセス(ワーカー)を作成できます。これらの子プロセスは同時に実行され、さまざまなタスクで動作し、マルチスレッドを効果的に実装できます。データ操作の問題。マルチスレッドは、出力が他の制御不能なイベントのシーケンスやタイミングに依存するレース条件などの問題につながる可能性があります。スレッド間の依存関係に対処する必要がないため、単一スレッド環境を最適化する方が簡単だと考えられていました。JavaScriptでマルチスレッドにWebワーカーを使用するにはどうすればよいですか?
JavaScriptでマルチスレッドにWebワーカーを使用するには、新しいワーカーオブジェクトを作成し、ワーカースレッドで実行されるJavaScriptファイルを指定する必要があります。その後、ポストメッサージメソッドを使用してワーカースレッドと通信し、オンメッセージイベントハンドラーを使用してメッセージからメッセージを受信できます。より速いですが、実行中のタスクの性質に依存します。 CPU集約型タスクの場合、マルチスレッドは、タスクを並行して実行できるようにすることで、パフォーマンスを大幅に改善できます。ただし、I/Oバウンドタスクの場合、これらのタスクはネットワーク速度などのCPUの制御以外の要因によって制限されることが多いため、マルチスレッドの利点はあまり顕著ではありません。 javascriptでのプログラミング?
マルチスレッドと非同期プログラミングは、両方とも複数のタスクを同時に管理するために使用される手法です。ただし、さまざまな方法で行います。マルチスレッドには複数の実行スレッドが含まれ、各スレッドは異なるタスクを実行します。一方、非同期プログラミングには実行の単一のスレッドが含まれますが、タスクを開始してから保留にして後で完了し、その間に他のタスクを実行できるようにします。 javascriptのスレッド間のデータ共有?
JavaScriptのスレッド間のデータ共有は、SharedArrayBufferとAtomicsを使用して実現できます。 SharedArrayBufferを使用すると、メインスレッドとワーカースレッド間でメモリを共有できますが、Atomicsは共有メモリで安全なアトミック操作を実行する方法を提供します。 、フロントエンド開発のためにJavaScriptでマルチスレッドを使用できます。ただし、マルチスレッドを可能にするWebワーカーは、DOMまたは他のWeb APIにアクセスできないことに注意することが重要です。したがって、それらは通常、DOMの操作やWebページとの対話を伴わないタスクに使用されます。
以上がJavaScriptのマルチスレッドの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ホットAIツール

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

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

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

Video Face Swap
完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

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

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

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

ホットトピック











フロントエンドのサーマルペーパーチケット印刷のためのよくある質問とソリューションフロントエンド開発におけるチケット印刷は、一般的な要件です。しかし、多くの開発者が実装しています...

JavaScriptは現代のWeb開発の基礎であり、その主な機能には、イベント駆動型のプログラミング、動的コンテンツ生成、非同期プログラミングが含まれます。 1)イベント駆動型プログラミングにより、Webページはユーザー操作に応じて動的に変更できます。 2)動的コンテンツ生成により、条件に応じてページコンテンツを調整できます。 3)非同期プログラミングにより、ユーザーインターフェイスがブロックされないようにします。 JavaScriptは、Webインタラクション、シングルページアプリケーション、サーバー側の開発で広く使用されており、ユーザーエクスペリエンスとクロスプラットフォーム開発の柔軟性を大幅に改善しています。

スキルや業界のニーズに応じて、PythonおよびJavaScript開発者には絶対的な給与はありません。 1. Pythonは、データサイエンスと機械学習でさらに支払われる場合があります。 2。JavaScriptは、フロントエンドとフルスタックの開発に大きな需要があり、その給与もかなりです。 3。影響要因には、経験、地理的位置、会社の規模、特定のスキルが含まれます。

この記事の視差スクロールと要素のアニメーション効果の実現に関する議論では、Shiseidoの公式ウェブサイト(https://www.shisido.co.co.jp/sb/wonderland/)と同様の達成方法について説明します。

JavaScriptを学ぶことは難しくありませんが、挑戦的です。 1)変数、データ型、関数などの基本概念を理解します。2)非同期プログラミングをマスターし、イベントループを通じて実装します。 3)DOM操作を使用し、非同期リクエストを処理することを約束します。 4)一般的な間違いを避け、デバッグテクニックを使用します。 5)パフォーマンスを最適化し、ベストプラクティスに従ってください。

JavaScriptの最新トレンドには、TypeScriptの台頭、最新のフレームワークとライブラリの人気、WebAssemblyの適用が含まれます。将来の見通しは、より強力なタイプシステム、サーバー側のJavaScriptの開発、人工知能と機械学習の拡大、およびIoTおよびEDGEコンピューティングの可能性をカバーしています。

同じIDを持つ配列要素をJavaScriptの1つのオブジェクトにマージする方法は?データを処理するとき、私たちはしばしば同じIDを持つ必要性に遭遇します...

Zustand非同期操作のデータの更新問題。 Zustand State Management Libraryを使用する場合、非同期操作を不当にするデータ更新の問題に遭遇することがよくあります。 �...
