Signatur
Beschreibung
Das Interface Worker gehört zur Web Workers API. Ein Worker führt JavaScript in einem eigenen Thread aus, getrennt vom Haupt-Thread, der für die Oberfläche zuständig ist. Rechenintensive Aufgaben wie Bildverarbeitung, Parsen großer JSON-Dateien, Kryptografie oder Kompression blockieren dadurch die Benutzeroberfläche nicht.
Erzeugt wird ein Worker mit new Worker(url, options). Haupt-Thread und Worker teilen sich keinen Speicher (Ausnahme: SharedArrayBuffer). Sie kommunizieren über postMessage() und das Ereignis message. Die Daten werden dabei mit dem Structured-Clone-Algorithmus kopiert, oder bei übertragbaren Objekten wie ArrayBuffer, MessagePort oder OffscreenCanvas ohne Kopie übertragen.
Wichtige Mitglieder:
Worker.prototype.postMessage(message, transfer): sendet eine Nachricht an den Worker.Worker.prototype.terminate(): beendet den Worker sofort, ohne dass er aufräumen kann.- Ereignis
message/onmessage: Nachricht vom Worker ist eingetroffen. - Ereignis
messageerror/onmessageerror: Nachricht konnte nicht deserialisiert werden. - Ereignis
error/onerror: im Worker-Skript ist ein nicht abgefangener Fehler aufgetreten.
Im Worker selbst ist self ein DedicatedWorkerGlobalScope. Dort gibt es kein window und kein document, also keinen DOM-Zugriff. Verfügbar sind dagegen fetch, IndexedDB, WebSocket, Timer, importScripts() (nur in klassischen Workern) und viele weitere Web-APIs.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $url Pflicht | string | URL | URL des Worker-Skripts. Das Skript muss gleichen Ursprungs sein (Same-Origin). Erlaubt sind außerdem blob:- und data:-URLs. Relative URLs werden relativ zum Dokument aufgelöst. |
|
| $options | { type?: 'classic' | 'module', credentials?: 'omit' | 'same-origin' | 'include', name?: string } | { type: 'classic', credentials: 'same-origin' } | type: 'module' lädt das Skript als ES-Modul, dann funktionieren import/export. credentials steuert, ob beim Laden von Modul-Workern Cookies mitgesendet werden. name ist ein Bezeichner für Debugging und steht im Worker als self.name zur Verfügung. |
Rückgabewert
Worker-Instanz. Das Skript wird asynchron geladen. Ist die URL ungültig, wird synchron ein SyntaxError geworfen, bei Verletzung der Same-Origin-Regel ein SecurityError. Scheitert das Laden selbst, wird ein error-Ereignis am Worker ausgelöst.Beispiele
Worker erstellen und Nachrichten austauschen (Modul-Worker)
// main.js
const worker = new Worker(new URL('./primes.js', import.meta.url), {
type: 'module',
name: 'primzahlen'
});
worker.addEventListener('message', (event) => {
console.log(`Gefunden: ${event.data.count} Primzahlen`);
worker.terminate(); // Ressourcen freigeben
});
worker.addEventListener('error', (event) => {
console.error('Worker-Fehler:', event.message, event.filename, event.lineno);
event.preventDefault();
});
worker.postMessage({ limit: 100_000 });
// primes.js
self.addEventListener('message', ({ data }) => {
const sieve = new Uint8Array(data.limit + 1);
let count = 0;
for (let i = 2; i <= data.limit; i++) {
if (!sieve[i]) {
count++;
for (let j = i * i; j <= data.limit; j += i) sieve[j] = 1;
}
}
self.postMessage({ count });
});
Worker per Promise kapseln (Anfrage/Antwort mit IDs)
// main.js
const worker = new Worker('hash-worker.js');
let nextId = 0;
const pending = new Map();
worker.onmessage = ({ data }) => {
const { id, result, error } = data;
const { resolve, reject } = pending.get(id);
pending.delete(id);
error ? reject(new Error(error)) : resolve(result);
};
const callWorker = (payload) =>
new Promise((resolve, reject) => {
const id = nextId++;
pending.set(id, { resolve, reject });
worker.postMessage({ id, payload });
});
// hash-worker.js
// self.onmessage = async ({ data }) => {
// try {
// const bytes = new TextEncoder().encode(data.payload);
// const hash = await crypto.subtle.digest('SHA-256', bytes);
// const hex = [...new Uint8Array(hash)].map(b => b.toString(16).padStart(2, '0')).join('');
// self.postMessage({ id: data.id, result: hex });
// } catch (e) {
// self.postMessage({ id: data.id, error: e.message });
// }
// };
const hash = await callWorker('hallo welt');
console.log(hash);
Große Daten ohne Kopie übertragen (Transferable)
const worker = new Worker('image-worker.js');
const buffer = new ArrayBuffer(8 * 1024 * 1024); // 8 MB
console.log('Vorher:', buffer.byteLength);
// Das zweite Argument überträgt den Besitz, statt zu kopieren
worker.postMessage({ buffer }, [buffer]);
console.log('Nachher:', buffer.byteLength); // im Haupt-Thread nun leer
Inline-Worker aus einem Blob erzeugen
const source = `
self.onmessage = ({ data }) => {
self.postMessage(data.map((n) => n * n));
};
`;
const blobUrl = URL.createObjectURL(new Blob([source], { type: 'text/javascript' }));
const worker = new Worker(blobUrl);
worker.onmessage = ({ data }) => {
console.log(data);
worker.terminate();
URL.revokeObjectURL(blobUrl);
};
worker.postMessage([1, 2, 3, 4]);