Signatur
Beschreibung
queueMicrotask() ist innerhalb von Dedicated, Shared und Service Workern über das globale Objekt (self) erreichbar. Die übergebene Funktion landet in der Mikrotask-Warteschlange. Das ist dieselbe Warteschlange, in der auch Promise-Reaktionen (then, await-Fortsetzungen) laufen. Sie wird ausgeführt, sobald der Aufrufstapel leer ist und bevor die Ereignisschleife die nächste Task annimmt, etwa ein message-Ereignis oder einen setTimeout-Callback.
Man verwendet die Methode, wenn Arbeit asynchron, aber so früh wie möglich erledigt werden soll. Typische Fälle:
- Mehrere synchrone Änderungen zu einem Vorgang bündeln, z. B. ein einziges
postMessage()statt vieler. - Einheitliches asynchrones Verhalten von APIs herstellen, damit ein Callback nie mal synchron und mal asynchron aufgerufen wird.
- Aufräumarbeiten erledigen, sobald der aktuelle Code abgeschlossen ist.
Anders als Promise.resolve().then(fn) legt queueMicrotask() kein Promise-Objekt an. Fehler aus dem Callback werden auch nicht in eine abgelehnte Promise umgewandelt. Sie werden als normale, nicht abgefangene Ausnahme gemeldet: Im Worker löst das das error-Ereignis am globalen Objekt aus, und das Worker-Objekt im Hauptthread erhält ebenfalls ein error-Ereignis.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $callback Pflicht | Function | Funktion ohne Argumente, die als Mikrotask ausgeführt wird. Ihr Rückgabewert wird ignoriert. Ist callback keine Funktion, wird ein TypeError geworfen. |
Rückgabewert
undefined zurück.Beispiele
Ausführungsreihenfolge im Worker
// worker.js
console.log('1: synchron');
setTimeout(() => console.log('4: Task (setTimeout)'), 0);
queueMicrotask(() => console.log('2: Mikrotask'));
Promise.resolve().then(() => console.log('3: Promise-Reaktion'));
Mehrere Updates zu einer Nachricht bündeln
// worker.js – schickt Fortschrittsmeldungen gebündelt an den Hauptthread
let pending = [];
let scheduled = false;
const report = (entry) => {
pending.push(entry);
if (!scheduled) {
scheduled = true;
queueMicrotask(() => {
self.postMessage({ type: 'batch', items: pending });
pending = [];
scheduled = false;
});
}
};
self.addEventListener('message', ({ data }) => {
for (const n of data.numbers) {
report({ n, square: n * n });
}
// Alle Ergebnisse gehen als EINE Nachricht hinaus
});
// main.js
// const worker = new Worker('worker.js');
// worker.onmessage = (e) => console.log(e.data.items.length);
// worker.postMessage({ numbers: [1, 2, 3] });
Callback immer asynchron aufrufen (Cache im Worker)
// worker.js
const cache = new Map();
const getData = (key, callback) => {
if (cache.has(key)) {
// Auch bei einem Cache-Treffer asynchron antworten → einheitliches Verhalten
queueMicrotask(() => callback(cache.get(key)));
return;
}
fetch(`/api/${key}`)
.then((res) => res.json())
.then((json) => {
cache.set(key, json);
callback(json);
});
};
self.onmessage = ({ data }) => {
getData(data.key, (result) => self.postMessage(result));
console.log('Anfrage angenommen');
};
// Wichtig · Fallstricke
- Die Warteschlange kann den Worker blockieren: Sie wird komplett abgearbeitet, auch wenn laufend neue Mikrotasks hinzukommen. Eine Mikrotask, die sich immer wieder selbst einreiht, verhindert, dass
message-Ereignisse oder Timer jemals verarbeitet werden. Für langwierige Arbeit, die unterbrochen werden darf, istsetTimeout()oderMessageChannelbesser geeignet. - Fehlerbehandlung: Eine Ausnahme im Callback lässt sich nicht mit
.catch()abfangen. Sie erreichtself.onerrorbzw. daserror-Ereignis amWorker-Objekt. Eintry/catchgehört deshalb in den Callback selbst. - Der Callback erhält keine Argumente. Werte übergibt man per Closure.
- Die Methode lässt sich nicht abbrechen: Es gibt keine ID und kein Gegenstück zu
clearTimeout(). Wer abbrechen können muss, prüft im Callback eine Markierungsvariable. - Kompatibilität: Chrome 71+, Firefox 69+, Safari 12.1+, Edge 79+, Node.js 11+. Für sehr alte Umgebungen gibt es einen Ersatz:
Promise.resolve().then(cb).catch(e => setTimeout(() => { throw e; })).