Start · Sprachen · JavaScript · Referenz · Window.queueMicrotask()

Window.queueMicrotask()

Methode

Reiht eine Funktion als Mikrotask ein. Sie läuft, sobald der aktuelle synchrone Code fertig ist und bevor die Ereignisschleife zum nächsten Task oder zum Rendern übergeht.

seit JavaScript Baseline: alle modernen Browser (seit 2020), Node. Kategorie: webapi

Signatur

Window.queueMicrotask(callback)

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');
1: synchron 2: synchron 3: Mikrotask 4: setTimeout (Makrotask)

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' });
Sende Batch: [{"event":"klick"},{"event":"scroll"},{"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');
Aufruf beendet Daten: Anna

// 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, requestAnimationFrame oder scheduler.postTask() verwenden.
  • Fehlerbehandlung: Ausnahmen im Callback werden als unbehandelter Fehler gemeldet (window.onerror bzw. das Event error). Sie führen nicht zu unhandledrejection. Ein try…catch um den Aufruf von queueMicrotask() 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; })).