JavaScriptDie Sprache verwendet einen einzelnen Thread Modell, das heißt, alle Aufgaben werden in einer Warteschlange angeordnet und es kann immer nur eine Sache gleichzeitig erledigt werden, was mit zunehmender Rechenleistung von Computern große Unannehmlichkeiten mit sich bringt . Das Potenzial von JavaScript kann nicht voll ausgeschöpft werden, wenn man bedenkt, dass die Datei API es JavaScript ermöglicht, eine Multithread-Umgebung für JavaScript zu erstellen Der Haupt-Thread weist den Unter-Thread einige Aufgaben zu, während der Haupt-Thread im Hintergrund ausgeführt wird, und die beiden stören sich nicht gegenseitig, bis der Unter-Thread die Berechnungsaufgabe abschließt und dann zurückkehrt Ergebnisse. Daher ist jeder Unterthread wie ein „Arbeiter“, der seine Arbeit stillschweigend erledigt:
Das Gleiche Domäneneinschränkung: Die vom Unterthread geladene Skriptdatei muss sich in derselben Domäne befinden wie die Skriptdatei des Hauptthreads. DOM-Einschränkung: Der Unterthread kann das DOM nicht lesen Das heißt, das Dokument, das Fenster und die übergeordneten Objekte können nicht vom untergeordneten Thread abgerufen werden. (Das Navigatorobjekt und das Standortobjekt können jedoch abgerufen werden.)new
, um einen neuen Sub-Thread zu erstellen -thread. Der Parameter derWorker-Methode ist eine Skriptdatei, die der Unterthread benötigt. Die abgeschlossene Aufgabe im obigen Code ist work.js Im lokalen Dateisystem muss die Skriptdatei von der Netzwerkseite stammen. Wenn der Download fehlschlägt, beispielsweise bei einem 404-Fehler, schlägt der untergeordnete Thread stillschweigend fehl.
if (window.Worker) { // 支持} else { // 不支持}
Die Parameter der postMessage-Methode sind die Signale, die vom Hauptthread an den untergeordneten Thread übergeben werden. Es kann entweder eine Zeichenfolge oder ein Objekt sein.
var worker = new Worker('work.js');
3.
EreignisÜberwachung des Unterthreads
worker.postMessage('hello world');
Rückruffunktion geben, um darauf zu warten Nachrichtenereignis.
worker.postMessage({method: 'each', args: ['work']});
//File: work.jsself.addEventListener('message', function(e) { self.postMessage('You said: ' + e.data); }, false);
Der Hauptthread muss auch eine Rückruffunktion für das Nachrichtenereignis angeben, um auf vom untergeordneten Thread gesendete Signale zu warten. 5.
Fehlerbehandlung'message', method = args = reply =);
6. Schließen Sie den untergeordneten Thread
// File: main.jsworker.addEventListener('message', function(e) { console.log(e.data); }, false);
worker.onerror(function(e) { console.log(e); });// orworker.addEventListener('error', function(e) { console.log(e); }, false);
anstelle der Adresse. Änderungen des Kommunikationsinhalts durch den Unter-Thread haben keine Auswirkungen auf den Haupt-Thread. Tatsächlich besteht der interne Betriebsmechanismus des Browsers darin, zuerst den Kommunikationsinhalt zu serialisieren und dann die serialisierte Zeichenfolge an den untergeordneten Thread zu senden, der sie dann wiederherstellt.
worker.terminate();
Arrays
Puffer und andere Objekte austauschen, die auch zwischen Threads gesendet werden können.self.close();
但是,用拷贝方式发送二进制数据,会造成性能问题。比如,主线程向子线程发送一个500MB文件,默认情况下浏览器会生成一个原文件的拷贝。为了解决这个问题,JavaScript允许主线程把二进制数据直接转移给子线程,但是一旦转移,主线程就无法再使用这些二进制数据了,这是为了防止出现多个线程同时修改数据的麻烦局面。这种转移数据的方法,叫做Transferable Objects。
如果要使用该方法,postMessage方法的最后一个参数必须是一个数组,用来指定前面发送的哪些值可以被转移给子线程。
worker.postMessage(arrayBuffer, [arrayBuffer]);
通常情况下,子线程载入的是一个单独的JavaScript文件,但是也可以载入与主线程在同一个网页的代码。假设网页代码如下:
<!DOCTYPE html> <body> <script id="worker" type="app/worker"> addEventListener('message', function() { postMessage('Im reading Tech.pro'); }, false); </script> </body></html>
我们可以读取页面的script,用worker来处理。
var blob = new Blob([document.querySelector('#workere').textContent]);
这里需要把代码当作二进制数据读取,所以使用Blob接口。然后,这个二进制对象转为URL,再通过这个URL创建worker。
var url = window.URL.createObjectURL(blob);var worker = new Worker(url);
部署事件监听代码。
worker.addEventListener('message', function(e) { console.log(e.data); }, false);
最后启动worker。
worker.postMessage('');
整个页面的代码如下:
<script> (function() { var blob = new Blob([document.querySelector('#worker').textContent]); var url = window.URL.createObjectURL(blob); var worker = new Worker(url); worker.addEventListener('message', function(e) { console.log(e.data); }, false); worker.postMessage(&#39;&#39;); })(); </script>