JavaScript/Web Worker

Aus SELFHTML-Wiki
< JavaScript(Weitergeleitet von JavaScript/Shared Worker)
Wechseln zu: Navigation, Suche

JavaScript ist eine Single-Thread-Umgebung, in der Scripte der Reihe nach abgearbeitet werden. Wenn ein Script sich verzögert oder abstürzt, sind keine weiteren Benutzereingaben mehr möglich.

Die Web Worker-API ermöglicht es, rechenintensive Skripte in einen sogenannten „Hintergrundthread“ auszulagern. Diese werden dann in ihrem eigenen Prozess, im Hintergrund und getrennt von der Website ausgeführt, ohne dabei die Benutzeroberfläche oder andere Skripts daran zu hindern, Interaktionen von Nutzern zu verarbeiten.

  • HTML5
  • Chrome
  • Firefox
  • IE 10
  • Opera
  • Safari

Details: caniuse.com

Anwendungsbeispiel[Bearbeiten]

Bei dieser Berechnung wäre der Browser für längere Zeit blockiert, eine Hinweis- oder Fehlermeldung wie „Nicht reagierendes Skript“ o.ä. wäre die Folge.

Beispiel: Ohne WebWorker
var i, summe = 0;
for (i = 0; i < 900000000; i++) {
    summe += i * i + Math.random();
};
alert(summe);

Erstellung des WebWorkers[Bearbeiten]

Beachten Sie: In den folgenden Beispielen wird für WebWorker die Variable webworker verwendet. Dieser Name ist aber veränderbar. Sollten Sie den Namen ändern, müssen Sie dies auch bei allen nachfolgenden Aktionen tun.

Zuerst muss der Code, der asynchron ausgeführt werden soll, in eine eigene Datei ausgelagert 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.

Beispiel: berechnung.js
var i, summe = 0;
for (i = 0; i < 900000000 ; i++) {
    summe += i * i + Math.random();
};

Im Hauptdokument wird nun auch der Code geändert:

Beispiel: Hauptdokument
<!doctype html>
<html>
<head>
  <meta charset="utf-8">
  <title>WebWorker</title>
</head>
<body>
  <script>
    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.

Daten senden und empfangen[Bearbeiten]

Wir erweitern daher unseren Code mit einem Eventlistener:

Beispiel: WebWorker
    var webworker = new Worker("berechnung.js");
    webworker.postMessage("Run");
    webworker.onmessage = function(n) {
    alert("Ergebnis: " + n.data);

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 wird mittels der Methode postMessage(); gemacht. Doch zuerst wird der Berechnungsprozess mit einer einfachen if-Abfrage gestartet. Um den Worker nicht ständig zu nennen benutzen wir in dem Fall self:

Beispiel: Ohne WebWorker
self.onmessage = function(n) {
    if (n.data == "Run") {
        var i, summe = 0;
        for (i = 0; i < 900000000; i++) {
            summe += i * i + Math.random();
        }
        self.postMessage(summe);
    }
};

Worker schließen[Bearbeiten]

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
  • im Hauptdokument

Datei[Bearbeiten]

In der Datei selbst erreicht man dies mit : self.close();

Daher hier der vollständige Code der Datei "berechnung.js:

Beispiel: berechnung.js - Schließen eines Web Workers
self.onmessage = function(n) {
    if (n.data == "Run") {
        var i, summe = 0;
        for (i = 0; i < 900000000; i++) {
            summe += i * i + Math.random();
        }
	self.postMessage(summe);
	self.close();
    }
};

Hauptdokument[Bearbeiten]

Im Hauptdokument wird dies durch webworker.terminate(); erreicht. Hier der vollständige Code der Hauptdatei:

Beispiel
<!doctype html>
<html>
<head>
  <meta charset="utf-8">
  <title>WebWorker</title>
</head>
<body>
  <script>
    var webworker = new Worker("berechnung.js");
    webworker.postMessage("Run");
    webworker.onmessage = function(n) {
      alert("Ergebnis: " + n.data);
      webworker.terminate();    
    };

  </script>
</body>
</html>

SharedWorker[Bearbeiten]

  • HTML5
  • Chrome
  • Firefox
  • Leer
  • Opera
  • Leer

Details: caniuse.com

Die SharedWorker-Schnittstelle stellt einen Worker bereit, der von verschiedenen Fenstern, iframes oder auch anderen Workern erreicht werden kann. Im Unterschied zu den Webworkern verwendet es eine andere Schnittstelle und hat ein anderes globales Scope, SharedWorkerGlobalScope.

Beachten Sie: Auf SharedWorker können Sie zwar von verschiedenen Browsing contexts zugreifen, sie müssen aber alle die gleiche Herkunft (Protokoll, Host und Port) haben. Siehe auch Same-Origin-Policy

Weblinks[Bearbeiten]

Web Worker

SharedWorker