Signatur
Beschreibung
queueMicrotask() legt eine Funktion in die Mikrotask-Warteschlange. Das ist dieselbe Warteschlange, in der auch Promise-Reaktionen (then, catch, await-Fortsetzungen) und MutationObserver-Rückrufe landen. Mikrotasks laufen, sobald der Aufrufstapel leer ist. Das passiert noch vor dem nächsten Makrotask (z. B. setTimeout, Events) und vor dem nächsten Rendern.
Die Methode eignet sich, wenn Code asynchron, aber so früh wie möglich laufen soll: etwa um mehrere synchrone Änderungen zu einer Aktion zu bündeln (Batching) oder um sicherzustellen, dass ein Rückruf immer asynchron aufgerufen wird. So vermeidet man Code, der mal synchron und mal asynchron zurückruft („Zalgo“). Anders als bei Promise.resolve().then(fn) wird kein Promise-Objekt erzeugt. Außerdem werden Fehler nicht als abgelehnte Promises verschluckt, sondern wie normale Ausnahmen gemeldet.
Die Methode gibt es global, sowohl in Window als auch in Workern (WorkerGlobalScope) und in Node.js. Man ruft sie meist einfach als queueMicrotask(fn) auf.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $callback Pflicht | Function | Die Funktion, die als Mikrotask ausgeführt wird. Sie bekommt keine Argumente und ihr Rückgabewert wird ignoriert. Ist callback keine Funktion, wird sofort ein TypeError geworfen. |
Beispiele
Ausführungsreihenfolge im Vergleich
console.log('1: synchron');
setTimeout(() => console.log('4: setTimeout (Makrotask)'), 0);
queueMicrotask(() => console.log('3: Mikrotask'));
console.log('2: synchron');
Mehrere Änderungen bündeln (Batching)
const pending = [];
let scheduled = false;
const sendLog = (entry) => {
pending.push(entry);
if (!scheduled) {
scheduled = true;
queueMicrotask(() => {
const batch = pending.splice(0);
scheduled = false;
console.log('Sende Batch:', JSON.stringify(batch));
});
}
};
sendLog({ event: 'klick' });
sendLog({ event: 'scroll' });
sendLog({ event: 'eingabe' });
Rückruf immer asynchron aufrufen (auch aus dem Cache)
const cache = new Map();
const getData = (key, callback) => {
if (cache.has(key)) {
// Nicht synchron zurückrufen, damit das Verhalten gleich bleibt
queueMicrotask(() => callback(cache.get(key)));
return;
}
fetch(`/api/${key}`)
.then((res) => res.json())
.then((data) => {
cache.set(key, data);
callback(data);
});
};
cache.set('user', { name: 'Anna' });
getData('user', (d) => console.log('Daten:', d.name));
console.log('Aufruf beendet');
// Wichtig · Fallstricke
- Die Oberfläche kann blockieren: Die Mikrotask-Warteschlange wird immer komplett abgearbeitet, bevor der Browser rendert oder Events verarbeitet. Das gilt auch für Mikrotasks, die währenddessen neu eingereiht werden. Wenn sich ein Mikrotask rekursiv immer wieder selbst einreiht, friert die Seite ein. Für längere Arbeit sollte man
setTimeout,requestAnimationFrameoderscheduler.postTask()verwenden. - Fehlerbehandlung: Ausnahmen im Callback werden als unbehandelter Fehler gemeldet (
window.onerrorbzw. das Eventerror). Sie führen nicht zuunhandledrejection. Eintry…catchum den Aufruf vonqueueMicrotask()fängt sie nicht ab. - Kein Abbrechen: Es gibt keine ID und kein Gegenstück wie
clearTimeout. Wer einen Mikrotask abbrechen will, muss selbst ein Flag prüfen. - Kompatibilität: Wird von Chrome 71+, Firefox 69+, Safari 12.1+, Edge 79+ und Node.js 11+ unterstützt. Für ältere Umgebungen gibt es diesen Polyfill:
Promise.resolve().then(cb).catch(e => setTimeout(() => { throw e; })).