Web Worker ist eine von HTML5 bereitgestellte Javascript-Multithreading-Lösung. Wir können rechenintensiven Code zur Ausführung übergeben, ohne dass die Benutzeroberfläche einfriert.
1: So verwenden Sie WorkerDas Grundprinzip von Web Worker besteht darin, mithilfe der Worker-Klasse eine JavaScript-Datei in den aktuellen Hauptthread von JavaScript zu laden, um einen neuen Thread zu öffnen, was zu einer nicht blockierenden Ausführung führt und eine Schnittstelle für den Datenaustausch zwischen dem Hauptthread bereitstellt und der neue Thread: postMessage, onmessage.
Schauen wir uns also ein Beispiel an, wie man es verwendet:
//worker.jsonmessage =function (evt){ var d = evt.data;//Gesendete Daten über evt.data abrufen postMessage(d);//Gesendete Daten an den Hauptthread senden}HTML-Seite: test.html
<!DOCTYPE HTML><html><head> <meta http-equiv=Content-Type content=text/html; charset=utf-8/> <script type=text/javascript>//WEB-Seiten-Hauptthread var worker = new Worker(worker.js); //Erstelle ein Worker-Objekt und übergebe ihm die URL des Skripts, das im neuen Thread ausgeführt wird worker.postMessage(hello world); //Sende Daten an den Worker worker.onmessage =function(evt){ //Empfangen Sie die Datenfunktion console.log(evt.data) vom Worker; //Geben Sie die vom Worker gesendeten Daten aus} </script> </head> <body></body>< /html>Nach dem Öffnen von test.html mit dem Chrome-Browser gibt die Konsole „Hallo Welt“ aus und zeigt damit an, dass das Programm erfolgreich ausgeführt wurde.
Anhand dieses Beispiels können wir erkennen, dass die Verwendung von Web Workern hauptsächlich in die folgenden Teile unterteilt ist:
WEB-Hauptthread:
1. Laden Sie eine JS-Datei über worker = new Worker( url), um einen Worker zu erstellen und eine Worker-Instanz zurückzugeben.
2. Senden Sie Daten über die Methode worker.postMessage(data) an den Worker.
3. Binden Sie die Methode worker.onmessage, um die vom Worker gesendeten Daten zu empfangen.
4. Sie können worker.terminate() verwenden, um die Ausführung eines Workers zu beenden.
neuer Worker-Thread:
1. Senden Sie Daten über die Methode postMessage(data) an den Hauptthread.
2. Binden Sie die Onmessage-Methode, um die vom Hauptthread gesendeten Daten zu empfangen.
2: Was kann der Arbeitnehmer tun?Jetzt wissen wir, wie man Web Worker verwendet, wozu er dient und welche Probleme er uns bei der Lösung helfen kann. Schauen wir uns ein Beispiel der Fibonacci-Folge an.
Wie wir alle wissen, wird die Fibonacci-Folge in der Mathematik rekursiv definiert: F0=0, F1=1, Fn=F(n-1)+F(n-2) (n>=2, n∈N*), Die übliche Implementierung von Javascript ist:
var fibonacci =function(n) { return n <2? n : arguments.callee(n -1) + arguments.callee(n -2);};//fibonacci(36)Die Ausführungszeit dieser Methode zur Berechnung der Fibonacci-Folge von 39 in Chrome beträgt 19097 Millisekunden, aber wenn es um die Berechnung von 40 geht, meldet der Browser direkt, dass das Skript beschäftigt ist.
Da JavaScript in einem einzelnen Thread ausgeführt wird, kann der Browser während des Berechnungsprozesses der Sequenz keine anderen JavaScript-Skripte ausführen, und der UI-Rendering-Thread wird ebenfalls angehalten, wodurch der Browser in einen Zombie-Zustand wechselt. Wenn Sie einen Web-Worker verwenden, um den Berechnungsprozess der Sequenz in einen neuen Thread zu verschieben, können Sie diese Situation vermeiden. Siehe konkrete Beispiele:
//fibonacci.jsvar fibonacci =function(n) { return n <2? n : arguments.callee(n -1) + arguments.callee(n -2);};onmessage =function(event) { var n = parseInt (event.data, 10); postMessage(fibonacci(n));};HTML-Seite: fibonacci.html
<!DOCTYPE HTML><html><head><meta http-equiv=Content-Type content=text/html;><title>web worker fibonacci</title><script type=text/javascript > onload =function(){ var worker =new Worker('fibonacci.js'); worker.addEventListener('message', function(event) { var timer2 = (new Date()).valueOf(); console.log( 'Result:'+event.data, 'Time:'+ timer2, 'Time take:'+ ( timer2 - timer ) }, var timer = ( new Date()).valueOf(); console.log('Berechnung starten: 40', 'Time:' + timer ); console.log('Die Timer-Funktion wurde beim Berechnen der Sequenz ausgeführt', 'Time:'+ (new Date()).valueOf() },1000); Ich habe bei der Berechnung der Sequenz ', 'time:'+ (new Date()).valueOf() ); } </script></head><body></body></html> ausgeführtÖffnen Sie fibonacci.html in Chrome und die Konsole erhält die folgende Ausgabe:
Beginnen Sie mit dem Zählen: 40 Zeit: 1316508212705
Als ich die Sequenz berechnet habe, habe ich die Zeit ausgeführt: 1316508212734
Die bei der Berechnung der Sequenz ausgeführte Timerfunktion: 1316508213735
Ergebnis: 102334155 Zeit: 1316508262820 Verstrichene Zeit: 50115
Dieses Beispiel zeigt, dass die im Worker durchgeführte Berechnung der Fibonacci-Sequenz keinen Einfluss auf die Codeausführung des Hauptthreads hat. Sie wird vollständig in einem eigenen unabhängigen Thread berechnet und die Ergebnisse werden erst nach der Berechnung an den Hauptthread zurückgesendet vollendet.
Mithilfe von Web-Workern können wir einige komplexe und umfangreiche Vorgänge im Front-End ausführen, ohne die Anzeige der Seite zu beeinträchtigen, und die ekelhafte Skript-Beschäftigt-Eingabeaufforderung wird nicht angezeigt.
Das folgende Beispiel verwendet einen Web-Worker, um Pixel in der Szene zu berechnen. Wenn die Szene geöffnet wird, wird sie einzeln gezeichnet. Ein Worker berechnet nur einen Pixelwert.
Drittens: Weitere Versuche des ArbeitersWir wissen bereits, dass Worker einen Worker erstellt, indem er eine URL empfängt. Können wir also Web-Worker verwenden, um einige Anfragen ähnlich wie JSONP zu stellen? Wie wir alle wissen, lädt JSONP JSON-Daten durch Einfügen von Skript-Tags, und das Skriptelement lädt und führt die aus Der gesamte Prozess blockiert. Es wäre großartig, wenn Web-Worker zum Implementieren des asynchronen Ladens verwendet werden könnten.
Im folgenden Beispiel werden 169,42 KB große JSON-Daten über drei verschiedene Methoden geladen: Web Worker, JSONP und Ajax.
// /aj/webWorker/core.jsfunction $E(id) { return document.getElementById(id);}onload =function() { //Laden durch Web Worker $E('workerLoad').onclick =function() { var url ='http://js.wcdn.cn/aj/mblog/face2'; var d = (new Date()).valueOf(); Worker(url); worker.onmessage =function(obj) { console.log('web worker: '+ ((new Date()).valueOf() }; E('jsonpLoad').onclick =function() { var url ='http://js.wcdn.cn/aj/mblog/face1'; Date()).valueOf(); STK.core.io.scriptLoader({ method:'post', url : url, onComplete : function() { console.log('jsonp: '+ ((new Date()) .valueOf() - d)); } }); //Laden Sie $E('ajaxLoad') durch ajax.onclick =function() { var url ='http://js.wcdn.cn/aj/mblog/face'; var d = (new Date()).valueOf(); STK.core.io.ajax({ url : url, onComplete : function( json) { console.log('ajax: '+ ((new Date()).valueOf() - d));HTML-Seite:/aj/webWorker/worker.html
<!DOCTYPE HTML><html><head><meta http-equiv=Content-Type content=text/html;><title>Worker-Beispiel: Daten laden</title><script src=http ://js.t.sinajs.cn/STK/js/gaea.1.14.js type=text/javascript></script><script type=text/javascript src=http://js.wcdn.cn/aj/webWorker/core.js></script></head><body> <input type=button id=workerLoad value=web worker load></input> < Eingabetyp=Schaltflächen-ID=jsonpLoad-Wert=jsonp-Last></input> <Eingabetyp=Schaltflächen-ID=ajaxLoad-Wert=Ajax-Laden></input></body></html>
HOST einrichten
127.0.0.1 js.wcdn.cn
Greifen Sie über http://js.wcdn.cn/aj/webWorker/worker.html auf die Seite zu und laden Sie die Daten dann auf drei Arten, um die Konsolenausgabe zu erhalten:
Web-Worker: 174jsonp: 25ajax: 38
Nach mehreren Versuchen stellte ich fest, dass der Zeitunterschied zwischen dem Laden von Daten über JSONP und Ajax nicht viel unterschiedlich ist und die Ladezeit von Web Worker immer auf einem hohen Niveau ist, sodass die Verwendung von Web Worker zum Laden von Daten immer noch relativ langsam ist Bei großen Datenmengen gibt es keinen Vorteil, es kann sein, dass Worker einige Zeit braucht, um neue Threads zu initialisieren. Es gibt keinen anderen Vorteil als die Nichtblockierung beim Laden.
Kann Web Worker das domänenübergreifende Laden von JS unterstützen? Dieses Mal greifen wir über http://127.0.0.1/aj/webWorker/worker.html auf die Schaltfläche „Web Worker laden“ zu Es erscheint folgende Fehlermeldung. Daraus können wir erkennen, dass Web Worker das domänenübergreifende Laden von JS nicht unterstützt, was eine schlechte Nachricht für Websites ist, die statische Dateien auf einem separaten statischen Server bereitstellen.
Daher können Web-Worker nur zum Laden von JSON-Daten in derselben Domäne verwendet werden, und Ajax kann dies bereits tun, was effizienter und vielseitiger ist. Lassen Sie den Arbeiter tun, was er gut kann.
Viertens: ZusammenfassungWeb-Worker sehen großartig aus, aber sie sind teuflisch.
Was wir tun können:
1. Sie können einen JS laden, um eine große Anzahl komplexer Berechnungen durchzuführen, ohne den Hauptprozess hängen zu lassen, und über postMessage und onmessage kommunizieren
2. Sie können über importScripts(url) zusätzliche Skriptdateien in den Worker laden.
3. Sie können setTimeout(), clearTimeout(), setInterval() und clearInterval() verwenden
4. Sie können XMLHttpRequest zum Senden von Anfragen verwenden
5. Kann auf einige Eigenschaften des Navigators zugreifen
Was sind die Einschränkungen:
1. JS kann nicht domänenübergreifend geladen werden
2. Der Code im Worker kann nicht auf das DOM zugreifen
3. Verschiedene Browser verfügen über unterschiedliche Implementierungen von Worker. Beispielsweise ermöglicht FF die Erstellung neuer Worker, Chrome jedoch nicht.
4. Nicht jeder Browser unterstützt diese neue Funktion
Das Obige ist der gesamte Inhalt dieses Artikels. Ich hoffe, dass er für das Studium aller hilfreich ist. Ich hoffe auch, dass jeder das VeVb Wulin Network unterstützt.