Signatur
Beschreibung
scheduler.postTask() gehört zur Prioritized Task Scheduling API. Die Methode reiht eine Aufgabe in die Aufgabenwarteschlange des Browsers ein. Anders als bei setTimeout() gibt man eine Priorität an: "user-blocking" für Aufgaben, die sofort für die Interaktion nötig sind, "user-visible" (Standard) für sichtbare, aber nicht blockierende Arbeit, und "background" für unkritische Arbeiten wie Logging, Analysedaten oder Vorab-Laden.
Die Methode gibt ein Promise zurück. Es wird mit dem Rückgabewert des Callbacks erfüllt oder abgelehnt, wenn der Callback eine Ausnahme wirft oder die Aufgabe über ein AbortSignal abgebrochen wird. Ein TaskSignal aus einem TaskController erlaubt zusätzlich, die Priorität einer bereits geplanten Aufgabe nachträglich zu ändern.
Typische Anwendungsfälle: lange Rechenarbeit in kleine Teile zerlegen, damit der Hauptthread ansprechbar bleibt (bessere Interaction to Next Paint), unwichtige Arbeit hinter wichtige stellen und verzögerte Aufgaben mit delay planen, die sich sauber abbrechen lassen. Das globale Objekt scheduler gibt es sowohl in window als auch in Workern.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $callback Pflicht | Function | Die auszuführende Funktion. Ihr Rückgabewert (auch ein Promise) wird zum Ergebnis des zurückgegebenen Promise. | |
| $options | Object | {} | Optionales Konfigurationsobjekt mit den folgenden Eigenschaften. |
| $options.priority | "user-blocking" | "user-visible" | "background" | "user-visible" | Unveränderliche Priorität der Aufgabe. Hat Vorrang vor der Priorität des signal. Wird sie gesetzt, lässt sich die Priorität später nicht mehr ändern. |
| $options.signal | AbortSignal | TaskSignal | Signal zum Abbrechen der Aufgabe. Ein TaskSignal steuert außerdem die (veränderbare) Priorität, solange priority nicht gesetzt ist. |
|
| $options.delay | number | 0 | Mindestverzögerung in Millisekunden, bevor die Aufgabe in die Warteschlange gelangt. |
Rückgabewert
callback erfüllt wird. Es wird abgelehnt, wenn der Callback eine Ausnahme wirft oder die Aufgabe abgebrochen wird (dann mit signal.reason, standardmäßig eine AbortError-DOMException).Beispiele
Aufgaben mit unterschiedlicher Priorität
// Reihenfolge richtet sich nach Priorität, nicht nach Aufrufreihenfolge
scheduler.postTask(() => console.log('background'), { priority: 'background' });
scheduler.postTask(() => console.log('user-visible'));
scheduler.postTask(() => console.log('user-blocking'), { priority: 'user-blocking' });
Lange Arbeit in Teilen mit Feature-Erkennung
const runTask = (fn, options) =>
'scheduler' in globalThis && 'postTask' in scheduler
? scheduler.postTask(fn, options)
: new Promise((resolve) => setTimeout(() => resolve(fn()), options?.delay ?? 0));
const processItems = async (items) => {
let sum = 0;
for (let i = 0; i < items.length; i += 1000) {
// Jeder Block ist eine eigene Aufgabe – der Hauptthread bleibt reaktionsfähig
sum += await runTask(
() => items.slice(i, i + 1000).reduce((a, b) => a + b, 0),
{ priority: 'background' }
);
}
return sum;
};
processItems(Array.from({ length: 10000 }, (_, i) => i)).then(console.log);
Verzögerte Aufgabe abbrechen
const controller = new AbortController();
scheduler
.postTask(() => console.log('Autosave'), { delay: 2000, signal: controller.signal })
.catch((err) => console.log(`Abgebrochen: ${err.name}`));
// Nutzer tippt weiter – Autosave verwerfen
controller.abort();
Priorität nachträglich ändern mit TaskController
const controller = new TaskController({ priority: 'background' });
scheduler
.postTask(() => 'Vorschau gerendert', { signal: controller.signal })
.then(console.log);
// Nutzer öffnet die Vorschau – jetzt dringend
controller.setPriority('user-blocking');
console.log(controller.signal.priority);
// Wichtig · Fallstricke
- Browser-Unterstützung: Chromium-Browser seit Version 94, Firefox seit 142; Safari unterstützt die API nicht. Immer mit
'scheduler' in globalThisprüfen und aufsetTimeout()ausweichen oder ein Polyfill verwenden. - Wenn
options.prioritygesetzt ist, wird die Priorität eines übergebenenTaskSignalignoriert undsetPriority()hat keine Wirkung auf diese Aufgabe. Das Abbrechen funktioniert aber trotzdem. - Nicht behandelte Ablehnungen (Fehler im Callback oder Abbruch) führen zu
unhandledrejection. Deshalb immer.catch()odertry/awaitverwenden. - Innerhalb einer Priorität gilt FIFO.
"user-blocking"sollte sparsam eingesetzt werden, sonst verdrängt es Rendering und andere Arbeit. delayist eine Mindestverzögerung, keine genaue Zeitangabe. In Hintergrund-Tabs kann der Browser zusätzlich drosseln.- Um nur kurz die Kontrolle an den Browser abzugeben, eignet sich
scheduler.yield()oft besser. Dabei bleibt die Fortsetzung vorn in der Warteschlange.