Signatur
Beschreibung
Das message-Ereignis tritt am Worker-Objekt im übergeordneten Kontext auf, also meist im Haupt-Thread. Es feuert, sobald der Worker mit self.postMessage() bzw. postMessage() eine Nachricht verschickt. Das Ereignisobjekt ist ein MessageEvent. In dessen Eigenschaft data liegen die gesendeten Daten.
Einen Handler kannst du auf zwei Arten registrieren: mit worker.addEventListener("message", handler) oder über die Eigenschaft worker.onmessage = handler. Mit addEventListener sind mehrere Listener möglich und du kannst sie gezielt mit removeEventListener entfernen. Die on-Eigenschaft nimmt dagegen nur einen einzigen Handler auf.
Die Daten werden mit dem Structured-Clone-Algorithmus kopiert. Übertragen lassen sich deshalb Objekte, Arrays, Map, Set, Date, ArrayBuffer, Blob und Ähnliches, aber keine Funktionen und keine DOM-Knoten. Große Binärdaten kannst du als Transferable (z. B. ArrayBuffer) ohne Kopie übergeben.
Typische Einsatzfälle sind aufwendige Berechnungen (Parsen, Bildverarbeitung, Kryptografie). Der Worker meldet damit Ergebnisse oder Fortschritt zurück, ohne die Oberfläche zu blockieren.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $type Pflicht | string | Der Ereignistyp, hier immer "message". |
|
| $handler Pflicht | (event: MessageEvent) => void | Callback, der das MessageEvent erhält. Wichtige Eigenschaften: data (gesendete Daten) und ports (übertragene MessagePorts). |
|
| $options | boolean | AddEventListenerOptions | false | Optionen wie once oder signal (AbortSignal zum Entfernen des Listeners). |
Rückgabewert
addEventListener gibt nichts zurück. Die Daten kommen über event.data im Handler an.Beispiele
Ergebnis einer Berechnung empfangen (addEventListener)
// main.js
const worker = new Worker(new URL('./fib-worker.js', import.meta.url), { type: 'module' });
worker.addEventListener('message', (event) => {
const { input, result } = event.data;
console.log(`fib(${input}) = ${result}`);
});
worker.postMessage(30);
// fib-worker.js
const fib = (n) => (n < 2 ? n : fib(n - 1) + fib(n - 2));
self.addEventListener('message', (event) => {
const n = event.data;
self.postMessage({ input: n, result: fib(n) });
});
Handler über die onmessage-Eigenschaft
const code = `self.onmessage = (e) => postMessage(e.data.toUpperCase());`;
const blobUrl = URL.createObjectURL(new Blob([code], { type: 'text/javascript' }));
const worker = new Worker(blobUrl);
worker.onmessage = (event) => {
console.log('Antwort:', event.data);
worker.terminate();
URL.revokeObjectURL(blobUrl);
};
worker.postMessage('hallo worker');
Fortschrittsmeldungen und Listener wieder entfernen
const worker = new Worker('progress-worker.js');
const onProgress = (event) => {
const { type, percent, result } = event.data;
if (type === 'progress') {
console.log(`Fortschritt: ${percent} %`);
} else if (type === 'done') {
console.log('Fertig:', result);
worker.removeEventListener('message', onProgress);
worker.terminate();
}
};
worker.addEventListener('message', onProgress);
worker.postMessage({ items: 1000 });
// progress-worker.js
// self.onmessage = ({ data }) => {
// for (let i = 1; i <= 4; i++) postMessage({ type: 'progress', percent: i * 25 });
// postMessage({ type: 'done', result: data.items * 2 });
// };
Worker-Antwort als Promise kapseln
const worker = new Worker('calc-worker.js');
let nextId = 0;
const request = (payload) => new Promise((resolve) => {
const id = nextId++;
const listener = ({ data }) => {
if (data.id !== id) return;
worker.removeEventListener('message', listener);
resolve(data.result);
};
worker.addEventListener('message', listener);
worker.postMessage({ id, payload });
});
const sum = await request([1, 2, 3, 4]);
console.log('Summe:', sum);
// calc-worker.js
// self.onmessage = ({ data }) =>
// postMessage({ id: data.id, result: data.payload.reduce((a, b) => a + b, 0) });
// Wichtig · Fallstricke
- Nicht serialisierbare Daten: Nicht klonbare Werte wie Funktionen, DOM-Knoten oder manche Klasseninstanzen lösen nicht
messageaus. Stattdessen wirft schonpostMessage()eineDataCloneError-Ausnahme. Kann eine eingegangene Nachricht auf der Empfängerseite nicht deserialisiert werden, feuertmessageerror. - Prototypen gehen verloren: Klasseninstanzen kommen als einfache Objekte an, und Getter bzw. Methoden fehlen danach.
- Fehler im Worker kommen nicht über
messagean. Für sie gibt es daserror-Ereignis amWorker-Objekt. - Transferables: Einen übertragenen
ArrayBuffer(postMessage(buf, [buf])) kann der Sender danach nicht mehr verwenden, seinebyteLengthist dann 0. - Sicherheit: Behandle
event.dataals nicht vertrauenswürdig, wenn der Worker Fremddaten verarbeitet. Schreibe die Daten also nicht ungeprüft perinnerHTMLins DOM (XSS-Gefahr). Worker-Skripte unterliegen der Same-Origin-Policy und der CSP-Direktiveworker-src. - Kompatibilität: Wird von allen modernen Browsern unterstützt. Modul-Worker (
{ type: 'module' }) funktionieren in Firefox erst ab Version 114. Node.js nutzt stattdessenworker_threadsmitworker.on('message'), dort kommen die Daten direkt ohneevent.dataan.