Start · Sprachen · JavaScript · Referenz · DedicatedWorkerGlobalScope

DedicatedWorkerGlobalScope

Schnittstelle

Globaler Gültigkeitsbereich eines dedizierten Web Workers, im Worker-Skript über <code>self</code> erreichbar. Stellt <code>postMessage()</code>, <code>close()</code> und das <code>message</code>-Ereignis bereit.

seit JavaScript Baseline: alle Browser (seit ca. 2012) Kategorie: webapi

Signatur

interface DedicatedWorkerGlobalScope extends WorkerGlobalScope

Beschreibung

DedicatedWorkerGlobalScope ist das globale Objekt in einem Skript, das per new Worker(url) gestartet wurde. Im Worker gibt es weder window noch document. Stattdessen verweisen self und globalThis auf eine Instanz dieser Schnittstelle. Sie erbt von WorkerGlobalScope (und damit von EventTarget) und hat deshalb auch Zugriff auf fetch(), setTimeout(), importScripts(), indexedDB, crypto, location und navigator.

Ein dedizierter Worker gehört genau zu dem Skript, das ihn erzeugt hat. Beide Seiten tauschen Daten über Nachrichten aus: Der Worker ruft self.postMessage() auf, um Daten an den Hauptthread zu schicken, und empfängt mit dem message-Ereignis, was der Hauptthread mit worker.postMessage() sendet. Die Daten werden dabei mit dem Structured-Clone-Algorithmus kopiert, ArrayBuffer und andere übertragbare Objekte lassen sich aber auch ohne Kopie übertragen.

Wichtige Bestandteile:

  • name: Der Name, den der Hauptthread über new Worker(url, { name }) vergeben hat. Nur lesbar.
  • postMessage(message, transfer?): Schickt eine Nachricht an den Hauptthread.
  • close(): Beendet den Worker von innen. Aufgaben, die schon in der Warteschlange stehen, werden verworfen.
  • requestAnimationFrame() / cancelAnimationFrame(): In Workern verfügbar, z. B. zusammen mit OffscreenCanvas.
  • Ereignisse: message, messageerror sowie die geerbten Ereignisse error, rejectionhandled und unhandledrejection.

Rechenintensive Aufgaben (Bildverarbeitung, Parsing, Kryptografie, Komprimierung) gehören in einen Worker, damit die Oberfläche flüssig bleibt. Mit dem DOM kann der Worker nicht direkt arbeiten, Änderungen an der Seite muss er als Nachricht an den Hauptthread schicken.

Parameter

Name Typ Default Beschreibung
$message Pflicht any Parameter von self.postMessage(): Daten, die per Structured Clone an den Hauptthread gehen. Funktionen, DOM-Knoten und Symbole sind nicht erlaubt.
$transfer Transferable[] | { transfer: Transferable[] } [] Parameter von self.postMessage(): Objekte wie ArrayBuffer, MessagePort, ImageBitmap oder OffscreenCanvas, deren Besitz ohne Kopie an den Empfänger übergeht.

Rückgabewert

Typ
DedicatedWorkerGlobalScope
Beschreibung
Der Wert von self bzw. globalThis im Worker. postMessage() und close() selbst geben undefined zurück.

Beispiele

Worker starten und Nachrichten austauschen

// main.js – Hauptthread
const worker = new Worker('worker.js', { name: 'rechner' });

worker.addEventListener('message', (event) => {
  console.log('Ergebnis vom Worker:', event.data);
});

worker.postMessage({ zahlen: [1, 2, 3, 4, 5] });

// worker.js – DedicatedWorkerGlobalScope
self.addEventListener('message', (event) => {
  const { zahlen } = event.data;
  const summe = zahlen.reduce((a, b) => a + b, 0);
  self.postMessage({ worker: self.name, summe });
});
Ergebnis vom Worker: { worker: 'rechner', summe: 15 }

Große Binärdaten ohne Kopie übertragen

// worker.js
self.onmessage = ({ data }) => {
  const pixel = new Uint8ClampedArray(data.buffer);
  // Bild in Graustufen umrechnen
  for (let i = 0; i < pixel.length; i += 4) {
    const grau = 0.299 * pixel[i] + 0.587 * pixel[i + 1] + 0.114 * pixel[i + 2];
    pixel[i] = pixel[i + 1] = pixel[i + 2] = grau;
  }
  // Buffer übertragen statt kopieren
  self.postMessage({ buffer: pixel.buffer }, [pixel.buffer]);
  console.log('Länge nach Transfer:', pixel.buffer.byteLength);
};
Länge nach Transfer: 0

Worker nach getaner Arbeit selbst beenden

// worker.js
self.addEventListener('message', async ({ data }) => {
  try {
    const antwort = await fetch(data.url);
    const json = await antwort.json();
    self.postMessage({ ok: true, anzahl: json.length });
  } catch (fehler) {
    self.postMessage({ ok: false, fehler: String(fehler) });
  } finally {
    self.close(); // Worker gibt seine Ressourcen frei
  }
});

console.log(self instanceof DedicatedWorkerGlobalScope);
true

Modul-Worker mit Fehlerbehandlung

// main.js
const worker = new Worker(new URL('./parser.js', import.meta.url), { type: 'module' });
worker.onmessage = (e) => console.log('Geparst:', e.data);
worker.onerror = (e) => console.error('Worker-Fehler:', e.message);
worker.postMessage('a,b,c');

// parser.js (ES-Modul im Worker)
self.onmessage = (e) => {
  self.postMessage(e.data.split(','));
};
self.addEventListener('unhandledrejection', (e) => {
  console.error('Unbehandelte Ablehnung im Worker:', e.reason);
});
Geparst: ['a', 'b', 'c']

// Wichtig · Fallstricke

  • Kein DOM: window, document und alert() gibt es im Worker nicht. Die Prüfung typeof window === 'undefined' taugt deshalb zur Erkennung, ob Code in einem Worker läuft.
  • Structured Clone: Wer Funktionen, DOM-Knoten oder Klasseninstanzen mit Prototyp verschickt, bekommt eine DataCloneError-Ausnahme bzw. verliert die Methoden. Schlägt die Deserialisierung auf der Empfängerseite fehl, wird messageerror ausgelöst.
  • Transfer: Nach der Übertragung ist das Originalobjekt beim Sender unbrauchbar (byteLength === 0).
  • close() vs. terminate(): self.close() beendet den Worker von innen, worker.terminate() von außen. In beiden Fällen laufen danach keine Callbacks mehr, auch keine ausstehenden setTimeout- oder fetch-Callbacks.
  • Same-Origin und CSP: Worker-Skripte müssen vom selben Ursprung stammen oder als blob:- bzw. data:-URL vorliegen, soweit die Content-Security-Policy (worker-src) das zulässt. Beim Öffnen über file:// blockieren viele Browser Worker ganz.
  • importScripts() funktioniert nur in klassischen Workern. In Modul-Workern ({ type: 'module' }) nutzt man stattdessen import. Modul-Worker werden seit 2023 von allen großen Browsern unterstützt.
  • In Node.js gibt es diese Schnittstelle nicht, dort übernimmt worker_threads mit parentPort diese Rolle.