Signatur
Beschreibung
setTimeout() steht in allen Worker-Kontexten zur Verfügung (DedicatedWorkerGlobalScope, SharedWorkerGlobalScope, ServiceWorkerGlobalScope) und funktioniert genauso wie window.setTimeout(). Die Methode plant einen einmaligen Rückruf ein und gibt eine numerische Timer-ID zurück, mit der sich der Timer über clearTimeout() wieder abbrechen lässt.
Innerhalb eines Workers ruft man die Methode meist ohne Präfix auf (setTimeout(...)) oder ausdrücklich über self.setTimeout(...). Typische Einsatzfälle sind verzögerte Wiederholungsversuche bei Netzwerkanfragen, Debouncing eingehender Nachrichten, Timeouts für lang laufende Berechnungen oder das Aufteilen großer Aufgaben in kleinere Abschnitte.
Die Verzögerung ist ein Mindestwert: Der Rückruf läuft frühestens nach delay Millisekunden, aber erst dann, wenn die Ereignisschleife des Workers frei ist. Blockierender synchroner Code im Worker verzögert daher auch die Ausführung des Timers.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $functionRef Pflicht | Function | string | Die Funktion, die nach Ablauf des Timers ausgeführt wird. Alternativ ein Code-String, der wie bei eval() ausgewertet wird (nicht empfohlen). |
|
| $delay | number | 0 | Verzögerung in Millisekunden. Werte kleiner 0, NaN oder fehlende Werte werden als 0 behandelt; der Rückruf läuft dann im nächsten Durchlauf der Ereignisschleife. |
| $...params | any | Zusätzliche Argumente, die beim Aufruf an functionRef übergeben werden. |
Rückgabewert
clearTimeout() übergeben werden kann.Beispiele
Verzögerte Antwort aus einem Dedicated Worker
// worker.js
self.addEventListener('message', (event) => {
const { task } = event.data;
// Antwort nach 500 ms zurückschicken
setTimeout((result) => {
self.postMessage({ task, result });
}, 500, `erledigt: ${task}`);
});
// main.js
const worker = new Worker('worker.js');
worker.onmessage = (e) => console.log(e.data);
worker.postMessage({ task: 'bericht' });
Timeout für fetch im Worker mit clearTimeout
// worker.js
const fetchWithTimeout = async (url, ms) => {
const controller = new AbortController();
const timerId = setTimeout(() => controller.abort(), ms);
try {
const response = await fetch(url, { signal: controller.signal });
return await response.json();
} finally {
clearTimeout(timerId); // Timer aufräumen, falls fetch schneller war
}
};
self.onmessage = async ({ data }) => {
try {
const json = await fetchWithTimeout(data.url, 3000);
self.postMessage({ ok: true, json });
} catch (err) {
self.postMessage({ ok: false, error: err.name });
}
};
Debouncing eingehender Nachrichten
// worker.js
let debounceId = null;
let latest = null;
self.onmessage = ({ data }) => {
latest = data;
clearTimeout(debounceId);
debounceId = setTimeout(() => {
// teure Berechnung nur für die letzte Eingabe
const words = latest.split(/\s+/).filter(Boolean).length;
self.postMessage({ words });
}, 300);
};
Promise-basierte Pause im Worker
// worker.js
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
const retry = async (fn, attempts = 3) => {
for (let i = 1; i <= attempts; i++) {
try {
return await fn();
} catch (err) {
if (i === attempts) throw err;
await sleep(2 ** i * 100); // exponentielles Backoff: 200, 400 ms
}
}
};
retry(() => fetch('/api/status').then((r) => r.json()))
.then((status) => self.postMessage(status));
// Wichtig · Fallstricke
- Kein Echtzeit-Timer:
delayist nur ein Mindestwert. Verschachtelte Timer (ab der 5. Ebene) werden auf mindestens 4 ms gedrosselt; synchroner, lang laufender Code im Worker verzögert alle Rückrufe. - Maximalwert: Verzögerungen größer als 2.147.483.647 ms (ca. 24,8 Tage) laufen über und führen zu einer sofortigen Ausführung.
- Code-Strings vermeiden: Ein String als
functionRefwird wieeval()ausgewertet, ist ein Sicherheitsrisiko und wird von einer strikten CSP (ohne'unsafe-eval') bzw. Trusted Types blockiert. - Service Worker: Der Browser darf einen inaktiven Service Worker jederzeit beenden – ausstehende Timer gehen dabei verloren. Für längere Vorgänge
event.waitUntil()nutzen und keine lang laufenden Timer voraussetzen. - Beendete Worker: Nach
worker.terminate()oderself.close()werden keine ausstehenden Timer mehr ausgeführt. - Timer-IDs gelten nur im jeweiligen Worker; eine ID aus dem Haupt-Thread kann im Worker nicht mit
clearTimeout()abgebrochen werden. - Kompatibilität: In allen modernen Browsern in Workern verfügbar; in Node.js-
worker_threadsgibtsetTimeout()dagegen einTimeout-Objekt statt einer Zahl zurück.