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

WorkerGlobalScope.queueMicrotask()

Methode

Reiht in einem Worker eine Mikrotask ein. Sie läuft, sobald der aktuelle Code fertig ist, aber bevor die Ereignisschleife die nächste Task (z. B. <code>message</code>) verarbeitet.

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

Signatur

WorkerGlobalScope.queueMicrotask(callback)

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

Typ
void
Beschreibung
Gibt 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'));
1: synchron 2: Mikrotask 3: Promise-Reaktion 4: Task (setTimeout)

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] });
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');
};
Anfrage angenommen (immer vor der Antwort, auch bei Cache-Treffer)

// 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, ist setTimeout() oder MessageChannel besser geeignet.
  • Fehlerbehandlung: Eine Ausnahme im Callback lässt sich nicht mit .catch() abfangen. Sie erreicht self.onerror bzw. das error-Ereignis am Worker-Objekt. Ein try/catch gehö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; })).