Signatur
Beschreibung
Die schreibgeschützte Eigenschaft scheduler von WorkerGlobalScope gibt das Scheduler-Objekt des aktuellen Worker-Kontexts zurück. Im Worker (Dedicated, Shared oder Service Worker) erreicht man sie direkt über scheduler oder self.scheduler. Sie ist das Gegenstück zu Window.scheduler im Hauptthread.
Über scheduler.postTask() lassen sich Aufgaben mit einer Priorität einplanen: "user-blocking", "user-visible" (Standard) oder "background". Die Aufgaben lassen sich außerdem verzögern und mit einem TaskController oder AbortSignal abbrechen bzw. neu priorisieren. Mit scheduler.yield() gibt eine lang laufende Funktion die Kontrolle kurz an die Ereignisschleife ab, damit z. B. eingehende message-Ereignisse verarbeitet werden können.
Im Worker ist das nützlich, wenn viele Aufgaben unterschiedlich dringend sind: Antworten auf Nachrichten des Hauptthreads laufen dann vor aufwendigen Hintergrundarbeiten wie Indexierung, Vorberechnung oder Cache-Pflege.
Rückgabewert
Scheduler-Objekt des Worker-Kontexts mit den Methoden postTask() und yield(). In Browsern ohne Unterstützung ist die Eigenschaft undefined.Beispiele
Aufgaben mit Priorität im Worker einplanen
// worker.js
if ('scheduler' in self) {
scheduler.postTask(() => console.log('Hintergrund'), { priority: 'background' });
scheduler.postTask(() => console.log('Sichtbar'), { priority: 'user-visible' });
scheduler.postTask(() => console.log('Blockierend'), { priority: 'user-blocking' });
} else {
console.log('Prioritized Task Scheduling API nicht verfügbar');
}
Nachrichten mit Rückgabewert verarbeiten
// worker.js
self.addEventListener('message', async (event) => {
const { numbers } = event.data;
const sum = await scheduler.postTask(
() => numbers.reduce((a, b) => a + b, 0),
{ priority: 'user-blocking' }
);
self.postMessage({ sum });
});
// main.js
const worker = new Worker('worker.js');
worker.onmessage = (e) => console.log('Summe:', e.data.sum);
worker.postMessage({ numbers: [1, 2, 3, 4] });
Hintergrundarbeit abbrechen und neu priorisieren
// worker.js
const controller = new TaskController({ priority: 'background' });
const job = scheduler.postTask(() => 'Index fertig', {
signal: controller.signal,
delay: 500
});
self.addEventListener('message', (e) => {
if (e.data === 'dringend') controller.setPriority('user-blocking');
if (e.data === 'abbrechen') controller.abort();
});
job
.then((result) => self.postMessage(result))
.catch((err) => self.postMessage(`Abgebrochen: ${err.name}`));
Lange Schleife mit scheduler.yield() unterbrechen
// worker.js
const processAll = async (items) => {
const results = [];
for (let i = 0; i < items.length; i++) {
results.push(items[i] * 2);
// alle 1000 Elemente die Ereignisschleife freigeben
if (i % 1000 === 0 && 'yield' in scheduler) {
await scheduler.yield();
}
}
return results;
};
processAll(Array.from({ length: 5000 }, (_, i) => i))
.then((r) => console.log(r.length));
// Wichtig · Fallstricke
- Browser-Unterstützung: Chromium-Browser ab Version 94 und Firefox ab 142. Safari unterstützt die API nicht. Deshalb immer per
'scheduler' in selfprüfen und eine Ausweichlösung vorsehen, z. B.setTimeoutoderqueueMicrotask. scheduler.yield()gibt es erst später (Chromium 129+). Prüfe diese Methode deshalb gesondert.- Die Prioritäten gelten nur innerhalb des jeweiligen Worker-Threads. Sie beeinflussen weder den Hauptthread noch andere Worker.
- Ein Abbruch über
AbortSignal/TaskControllerlässt das Promise mit einemAbortErrorscheitern. Ohnecatch()entsteht eine unbehandelte Promise-Ablehnung. - Die Eigenschaft ist schreibgeschützt. Eine Zuweisung an
self.schedulerhat keine Wirkung. - Eine bereits laufende Aufgabe wird nicht unterbrochen. Lange synchrone Arbeit muss man selbst in Teile zerlegen (z. B. mit
yield()).