JavaScript にはマルチスレッドがないことは間違いありません。 1 つのことを完了したら、次のことを実行します。 1 つのことを実行するのに時間がかかる場合。長時間使用すると、ブラウザが一定時間フリーズし、ユーザーの操作に応答しなくなります。どうすればよいでしょうか。ありがたいことに、HTML5 はマルチスレッドを実装するメカニズムを提供しています。これまでにこのような優れた機能を使用したことがあるはずですが、それは問題ではありません。一緒に確認しましょう。 1. Workerクラス 1. メソッドの紹介
new
Worker(arg): パラメータは、「myworker」など、スレッドによって実行されるコードが配置されているjsファイルを示します。 .js', コンストラクターは当然 Worker クラスのインスタンスを返します (2) worker.postMessage(message): このメソッドは、メインスレッドからサブスレッド、またはサブスレッドからサブスレッドにメッセージを送信することを意味します。メッセージは通常
文字列ですが、js オブジェクト を文字列に変換して送信することもできます (3) 誰かがワーカーにメッセージ イベント を送信することもあります。このワーカー インスタンスにメッセージを送信すると、イベントがトリガーされます。イベント オブジェクトの data
属性を使用して、投稿された値 を取得することができます。Wker クラスの API が非常に単純であることがわかります。最も一般的に使用されるメソッドは 2 つだけです。実際の例で見てみましょう。
//main.html <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>main</title></head><body> <p id="out"></p> <input type="text" name="" id="txt"> <button id="btn">发送</button> <script type="text/javascript"> var out = document.getElementById("out"); var btn = document.getElementById("btn"); var txt = document.getElementById("txt"); var worker = new Worker("thread1.js"); btn.addEventListener("click",function(){ var postData = txt.value; worker.postMessage(postData); },false); worker.addEventListener('message',function(e){ out.innerText = e.data; },false); </script></body></html>
テキストボックスに「Big~Bear」と入力して送信ボタンをクリックすると、以下のような効果が現れます
簡単な分析のため、メインでthead1.jsでWorkerインスタンスworkerを作成しました。ボタンをクリックすると、postMessage メソッドが呼び出され、テキスト ボックス内の内容が thread1.js に送信されます。それだけです。メッセージ イベントをリッスンし、メイン スレッドはメッセージの送信時にイベントをトリガーし、コールバック関数を実行します。コールバック関数は、イベント オブジェクトから送信された値を取得し、「ハンサム!」を追加します。この値に戻してから戻します。メインスレッドはワーカーのメッセージイベントもリッスンするので、メッセージが通過するとトリガーされ、メッセージの内容が p に表示されるため、上記の効果がわかります。
おそらくこれを何の目的で使用しますか?ここでは、メインスレッドで「ハンサム!」を追加する操作をいつでも完了できます。その複雑さは O(1) です (笑、最近アルゴリズムを勉強しています!)。しかし、そうでない場合は、簡単操作 毛織物?この方法の利点は、サブスレッドが実行する処理がどれほど複雑であっても、メインスレッドは、サブスレッドがデータを処理した後は実行し続けることです。それを引き継ぐことができます。 ルー先生は、サブスレッドで new Worker() を呼び出すことで新しいサブスレッドを作成できることがわかりました。これは不可能であり、未定義のエラーが報告されます。これは、Worker コンストラクターを呼び出すことができないことを意味します。最初は間違っていると思いましたが、後で公式ドキュメントを確認したところ、関連する記述がないことがわかりました。
メインスレッドで複数のサブスレッドを呼び出す例を見てみましょう:
//thread1.js onmessage = function(event){ var res = event.data+"帅气!"; postMessage(res); }
//main.html <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>main</title> </head> <body> <div id="out"></div> <input type="text" name="" id="txt"> <button id="btn">发送</button> <script type="text/javascript"> var out = document.getElementById("out"); var btn = document.getElementById("btn"); var txt = document.getElementById("txt"); var worker1 = new Worker("thread1.js"); var worker2 = new Worker("thread2.js"); btn.addEventListener("click",function(){ var postData = txt.value; worker1.postMessage(postData); },false); worker1.addEventListener('message',function(e){ worker2.postMessage(e.data); },false); worker2.addEventListener('message',function(e){ out.innerText = e.data; },false); </script> </body> </html>
//thread1.js onmessage = function(event){ var res = event.data+"帅气!"; postMessage(res); }
メインスレッドは、タスクを完了するために 2 つのスレッドを必要とします。worker1 と 2 の 2 つのスレッドが作成されます。最初に worker1 をリクエストし、返されたスレッドを取得します。そして、worker2にデータをリクエストすると同時に、worker1が処理したデータをw
order2に渡して処理し、最終結果を取得してページに表示します。
以下の例のように、他の js ファイルを子スレッドに導入して呼び出すことができます。 //thread2.js
onmessage = function(event){
var res = event.data+"没骗你哟!";
postMessage(res);
close();
}
//main.html
<!DOCTYPE html><html lang="en"><head>
<meta charset="UTF-8">
<title>main</title></head><body>
<p id="out"></p>
<input type="text" name="" id="txt">
<button id="btn">发送</button>
<script type="text/javascript">
var out = document.getElementById("out");
var btn = document.getElementById("btn");
var txt = document.getElementById("txt");
var worker1 = new Worker("thread1.js");
btn.addEventListener("click",function(){
var postData = txt.value;
worker1.postMessage(postData);
},false);
worker1.addEventListener('message',function(e){
out.innerText = e.data;
},false); </script></body></html>
//thread1.js
importScripts('tools.js')
onmessage = function(event){
var res = handler(event.data);
postMessage(res);
}
2. SharedWorkerクラス
SharedWorkerの本質は、異なるスレッドが1つのスレッドを共有することができ、そのデータも共有されます。
使用方法 1:
//tools.js function handler(data){ return data+"加油加油!" }
//main.html <!DOCTYPE HTML><head> <title>Shared workers: demo 1</title></head><body> <p id="log"></p><script> var worker = new SharedWorker('shared.js'); var log = document.getElementById('log'); worker.port.onmessage = function(e) { // note: not worker.onmessage! log.textContent += '\n' + e.data; }</script></body></html>
これは
w3cから引用した例です。まず 2 番目の方法を見てから分析しましょう
。<!DOCTYPE HTML> <html> <head> <title>Shared workers: demo 2</title> </head> <body> <p id="log"></p> <script> var worker = new SharedWorker('shared.js'); var log = document.getElementById('log'); worker.port.addEventListener('message', function(e) { log.textContent += '\n' + e.data; }, false); worker.port.start(); // note: need this when using addEventListener worker.port.postMessage('ping');</script> </body></html>
//shared onconnect = function(e) { var port = e.ports[0]; port.postMessage('Hello World!'); port.onmessage = function(e) { port.postMessage('pong'); // not e.ports[0].postMessage! // e.target.postMessage('pong'); would work also } }
第一种方法中是使用事件句柄的方式将听message事件,不需要调用worker.port.start(),第二种方法是通过addEventListener()方法监听message事件,需要worker.port.start()方法激活端口。他们不同于worker,当有人和他通信时触发connect事件,然后他的message事件是绑定在messagePort对象上的,不想worker那样,你可以回头看看worker是怎么做的。
那么sharedWorker是怎么共享数据的呢?请看下面的例子。
//main1 和main2都是这样 <!DOCTYPE HTML> <html> <head> <title>Shared workers: demo 2</title> </head> <body> <p id="log"></p> <input type="text" name="" id="txt"> <button id="get">get</button> <button id="set">set</button> <script> var worker = new SharedWorker('shared.js'); var get = document.getElementById('get'); var set = document.getElementById('set'); var txt = document.getElementById('txt'); var log = document.getElementById('log'); worker.port.addEventListener('message', function(e) { log.innerText = e.data; }, false); worker.port.start(); // note: need this when using addEventListener set.addEventListener('click',function(e){ worker.port.postMessage(txt.value); },false); get.addEventListener('click',function(e){ worker.port.postMessage('get'); },false);</script></body></html>
//shared var data; onconnect = function(e) { var port = e.ports[0]; port.onmessage = function(e) { if(e.data=='get'){ port.postMessage(data); }else{ data=e.data; } } }
这里分析一波,我们在main1.html的文本框输入数据,点击set,然后在main2.html中点击get法现能够获取到我们在main1.html中设置的数据,这说明我们的sharedWorker事实上是单例的,就像java中的static类一样,不管new多少个,实际上只有一个,这样我们的不同线程就可以共享到sharedWorker中的数据了。这里把图给上,记得有篇文章没给图,然后有人给我建议了,问能不能给图。
最后来小结一下,worker和sharedWorker没有什么悬糊的,就是把台前的工作搬到幕后去做,不打断台前的工作。正所谓台上十分钟,台下十年功,如果你把台下的十年供放到台上做,观众的唾沫星子早就把你淹死了,所以说那些费事费力的工作还是放到台下去,台上只用展示你最好的一面的好了,十分钟足以!
以上がHTML5新機能マルチスレッド(Worker SharedWorker)の詳細コード説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。