Nutze die Event-Loop, parallelisiere deine Promises richtig und mache die asynchrone Fehlerbehandlung zuverlässig.
Diese Lektion in Kodokon öffnenDas Ausführungsmodell stützt sich auf eine Makrotask-Warteschlange (setTimeout, I/O) und eine Mikrotask-Warteschlange (.then, await, queueMicrotask). Nach jeder Task leert die Engine die Mikrotask-Warteschlange vollständig, bevor sie weitermacht. Direkte Folge: Eine aufgelöste Promise läuft immer vor einem setTimeout(fn, 0), und eine zu lange Kette von Mikrotasks kann das Rendering genauso sicher einfrieren wie eine synchrone Schleife.
console.log("start");
setTimeout(() => console.log("macrotask"), 0);
Promise.resolve().then(() => console.log("microtask"));
console.log("end");
// start, end, microtask, macrotaskasync/await ist Zucker auf Promises, doch versteckt es eine Performance-Falle: Jedes await innerhalb einer Schleife serialisiert die Operationen. Wenn die Anfragen unabhängig sind, starte sie zuerst alle und warte dann mit Promise.all auf den Stapel. Bei drei Anfragen von je 100 ms kostet die sequenzielle Version 300 ms, die parallele 100 ms.
const fetchUser = (id) => new Promise((res) => {
setTimeout(() => res({ id }), 100);
});
async function loadSequential(ids) {
const users = [];
for (const id of ids) {
users.push(await fetchUser(id)); // ~100 ms each
}
return users;
}
async function loadParallel(ids) {
return Promise.all(ids.map(fetchUser)); // ~100 ms total
}Wähle den richtigen Kombinator für den Fehlervertrag, den du brauchst: Promise.all lehnt beim ersten Fehler ab (alles oder nichts), allSettled wartet auf alle und beschreibt jedes Ergebnis, race nimmt die erste Beilegung (Erfolg oder Fehler, nützlich für einen Timeout), any nimmt den ersten Erfolg und lehnt nur ab, wenn alles fehlschlägt. Für ein Dashboard, das Teilergebnisse zeigen muss, ist allSettled fast immer die richtige Wahl.
const tasks = [
Promise.resolve("profile loaded"),
Promise.reject(new Error("network unavailable")),
];
const results = await Promise.allSettled(tasks);
for (const r of results) {
if (r.status === "fulfilled") {
console.log("success:", r.value);
} else {
console.error("failure:", r.reason.message);
}
}console.log, ein Promise.resolve().then-Callback und ein setTimeout(fn, 0)-Callback?try { doAsync(); } catch (e) {} ohne await die Ablehnung von doAsync nicht ab?