Start · Sprachen · JavaScript · Referenz · DedicatedWorkerGlobalScope: message

DedicatedWorkerGlobalScope: message

Ereignis

Wird im globalen Gültigkeitsbereich eines Dedicated Workers ausgelöst, wenn der Worker per <code>worker.postMessage()</code> eine Nachricht vom erzeugenden Skript erhält.

seit JavaScript Baseline: alle Browser Kategorie: webapi

Signatur

self.addEventListener("message", handler)

Beschreibung

Das message-Ereignis tritt auf dem DedicatedWorkerGlobalScope (im Worker erreichbar über self bzw. globalThis) ein, sobald das Elternskript – meist der Hauptthread – mit worker.postMessage(data, transfer) eine Nachricht sendet. Das Ereignisobjekt ist ein MessageEvent. Seine Eigenschaft data enthält eine per Structured Clone kopierte Fassung der gesendeten Daten, ports enthält die mitübertragenen MessagePort-Objekte.

Einen Listener registriert man entweder mit self.addEventListener("message", handler) oder über die Eigenschaft self.onmessage = handler. Mit addEventListener lassen sich mehrere Handler anhängen und über removeEventListener wieder entfernen. onmessage erlaubt dagegen nur genau einen Handler, der bei jeder neuen Zuweisung ersetzt wird.

Typische Einsatzfälle sind rechenintensive Aufgaben wie Bildverarbeitung, Parsing oder Kryptografie, die den Hauptthread nicht blockieren sollen. Der Worker empfängt einen Auftrag, verarbeitet ihn und schickt das Ergebnis mit self.postMessage() zurück. Dieses Ergebnis kommt dann als message-Ereignis auf dem Worker-Objekt im Hauptthread an.

Das Ereignis lässt sich nicht abbrechen und steigt nicht auf (kein Bubbling). Nachrichten, die sich nicht deserialisieren lassen, lösen statt message das Ereignis messageerror aus.

Parameter

Name Typ Default Beschreibung
$type Pflicht string Der Ereignistyp, hier "message".
$handler Pflicht (event: MessageEvent) => void Callback, der ein MessageEvent erhält. Wichtige Eigenschaften: data (die Nutzdaten), ports (übertragene MessagePorts), origin und lastEventId (bei Dedicated Workers meist leer).
$options boolean | AddEventListenerOptions false Optionen wie once, signal (AbortSignal zum Entfernen) oder capture.

Rückgabewert

Typ
void
Beschreibung
addEventListener gibt nichts zurück. Der Rückgabewert des Handlers wird ignoriert.

Beispiele

Auftrag im Worker empfangen und beantworten (addEventListener)

// worker.js
self.addEventListener("message", (event) => {
  const { numbers } = event.data;
  const sum = numbers.reduce((a, b) => a + b, 0);
  self.postMessage({ sum });
});

// main.js
const worker = new Worker("worker.js");
worker.addEventListener("message", (e) => console.log("Summe:", e.data.sum));
worker.postMessage({ numbers: [1, 2, 3, 4] });
Summe: 10

Kurzform mit onmessage und Nachrichtentypen

// worker.js
self.onmessage = ({ data }) => {
  switch (data.type) {
    case "upper":
      self.postMessage(data.text.toUpperCase());
      break;
    case "stop":
      self.close(); // Worker beendet sich selbst
      break;
  }
};

// main.js
const worker = new Worker("worker.js");
worker.onmessage = (e) => console.log(e.data);
worker.postMessage({ type: "upper", text: "hallo worker" });
worker.postMessage({ type: "stop" });
HALLO WORKER

Listener per removeEventListener und AbortSignal entfernen

// worker.js
const onInit = (event) => {
  console.log("Init-Konfiguration:", event.data);
  // nur die erste Nachricht als Init behandeln
  self.removeEventListener("message", onInit);
};
self.addEventListener("message", onInit);

const controller = new AbortController();
self.addEventListener("message", (e) => {
  if (e.data === "ende") controller.abort();
  else console.log("Nachricht:", e.data);
}, { signal: controller.signal });
Init-Konfiguration: {...} Nachricht: ...

ArrayBuffer ohne Kopie übertragen (Transferable)

// main.js
const worker = new Worker("worker.js");
const buffer = new Uint8Array(1024 * 1024).buffer;
worker.postMessage(buffer, [buffer]);
console.log(buffer.byteLength); // 0 – Besitz übertragen

// worker.js
self.addEventListener("message", (e) => {
  console.log("Empfangen:", e.data.byteLength, "Bytes");
});
0 Empfangen: 1048576 Bytes

// Wichtig · Fallstricke

  • Structured Clone: Funktionen, DOM-Knoten und Klasseninstanzen (deren Prototyp dabei verloren geht) lassen sich nicht übertragen. Nicht klonbare Werte führen beim Sender zu einer DataCloneError-Ausnahme. Schlägt die Deserialisierung beim Empfänger fehl, wird messageerror statt message ausgelöst.
  • Leistung: Große Datenmengen werden kopiert. Mit Transferables wie ArrayBuffer, MessagePort oder OffscreenCanvas lässt sich das Kopieren vermeiden. Der Sender verliert dann aber den Zugriff auf das Objekt.
  • Reihenfolge: Nachrichten, die vor dem Registrieren des Listeners gesendet wurden, werden in eine Warteschlange gestellt und zugestellt, sobald das Worker-Skript geladen ist. Den Listener sollte man trotzdem synchron auf oberster Ebene des Skripts registrieren und nicht erst nach einem await.
  • Sicherheit: event.origin ist bei Dedicated Workers in der Regel leer. Kommen die Daten ursprünglich aus unsicheren Quellen, müssen sie im Worker trotzdem geprüft werden.
  • Bei Module Workers (new Worker(url, { type: \"module\" })) funktioniert das Ereignis identisch.
  • Kompatibilität: Das Ereignis wird von allen modernen Browsern unterstützt. In Node.js heißt das Gegenstück parentPort.on(\"message\") aus worker_threads.