JavaScript/API/Web Worker
Mit Hilfe des WebWorkers können wir Skripte "auslagern". Diese werden dann in dem sogenannten "Hintergrundthread" ausgeführt.
Bei dieser Berechnung hier z.B. würde der Browser ohne den WebWorker melden, dass die Seite nicht mehr reagiert, oder ähnliches.
<html> <head> <title>Ohne WebWorker</title> </head> <body> <script type="text/javascript"> var ergeb = 0; for (var i = 0; i < 900000000 ; i++) { ergeb += i * i + Math.random(); }; alert(ergeb); </script> </body> </html>
Inhaltsverzeichnis |
[Bearbeiten] Erstellung des WebWorkers
Wichtig: Ich weise das Objekt der Variabel "webworker" zu, dieser Name ist aber veränderbar. Wichtig dabei ist, falls Sie den Namen ändern sollten, diesen auch bei den nachfolgenden Aktionen zu ändern.
Zuerst muss der Code, der asynchron ausgeführt werden soll in eine extra Datei geschrieben werden. Funktionen wie document.write(); , alert();
oder ähnliches funktionieren dabei nicht, das liegt daran, dass der WebWorker keinen Zugriff auf das DOM hat. Das Ergebnis unserer Aufgabe muss daher auf anderem Wege wieder in das Originaldokument kommen.
Hier berechnung.js :
var ergeb = 0; for (var i = 0; i < 900000000 ; i++) { ergeb += i * i + Math.random(); };
In dem Hauptdokument wird nun auch der Code geändert:
<html> <head> <title>WebWorker</title> </head> <body> <script type="text/javascript"> var webworker = new Worker("berechnung.js"); </script> </body> </html>
Es wird ein neues Objekt "Worker" erstellt, das auf die Datei "berechnung.js" verweist. So erscheint die Meldung des Browsers zwar nicht mehr, aber wir erhalten nach entsprechender Zeit auch kein Ergebnis. Deshalb müssen Daten gesendet und empfangen werden.
[Bearbeiten] Daten zu dem Worker senden und empfangen
Wir erweitern daher unseren Code mit einem Eventlistener:
<html> <head> <title>WebWorker</title> </head> <body> <script type="text/javascript"> var webworker = new Worker("berechnung.js"); webworker.postMessage("Run"); webworker.onmessage = function(n) { alert("Ergebnis: " + n.data); }; </script> </body> </html>
Die Methode postMessage();
verschickt die Daten (Nachricht) "Run" an die Datei "berechnung.js". Sendet nun die Datei "berechnung.js" an die Hauptdatei das Ergebnis, so löst diese die Funktion aus das Ergebnis mit Hilfe von alert();
zu auszugeben. Dabei enthält die Eigenschaft data
das eigentliche Ergebnis.
In der Datei "berechung.js" muss nun die Nachricht verschickt werden. Dies wir von der Methode postMessage();
gemacht. Doch zuerst wird der Berechnungsprozess mit einer einfachen if
Abfrage gesartet. Um den Worker nicht ständig zu nennen benutzen wir in dem Fall self
:
self.onmessage = function(n) { if (n.data == "Run") { var ergeb = 0; for (var i = 0; i < 900000000; i++) { ergeb += i * i + Math.random(); } self.postMessage(ergeb); } };
[Bearbeiten] Worker schließen
Es ist natürlich ratsam, den Worker wieder zu schließen, um nicht unnötige Prozessor oder Arbeitsspeicher Auslastungen zu produzieren. Es gibt 2 Möglichkeiten einen Worker zu beenden:
- In der Datei selbst
- Oder in dem Hauptdokument
[Bearbeiten] Datei
In der Datei selber erreicht man dies mit : self.close();
Daher hier der vollständige Code der Datei "berechnung.js:
self.onmessage = function(n) { if (n.data == "Run") { var ergeb = 0; for (var i = 0; i < 900000000; i++) { ergeb += i * i + Math.random(); } self.postMessage(ergeb); self.close(); } };
[Bearbeiten] Hauptdokument
In dem Hauptdokument wird dies durch webworker.terminate();
erreicht.
Hier der vollständige Code der Hauptdatei:
<html> <head> <title>WebWorker</title> </head> <body> <script type="text/javascript"> var webworker = new Worker("berechnung.js"); webworker.postMessage("Run"); webworker.onmessage = function(n) { alert("Ergebnis: " + n.data); }; webworker.terminate(); </script> </body> </html>