JavaScript läuft in einem einzigen Thread. Netzwerkzugriffe und Timer blockieren ihn trotzdem nicht, weil ihre Ergebnisse später über die Event Loop geliefert werden. Ein Promise steht für einen solchen zukünftigen Wert. async/await ist die gut lesbare Syntax, mit der du Promises verarbeitest.
Promises
Ein Promise hat einen von drei Zuständen: pending (ausstehend), fulfilled (erfüllt) oder rejected (abgelehnt). Mit then, catch und finally reagierst du auf das Ergebnis. Jeder dieser Aufrufe gibt ein neues Promise zurück, deshalb kannst du sie verketten.
const wait = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
wait(500)
.then(() => fetch('/api/user'))
.then((res) => res.json())
.catch((err) => console.error(err))
.finally(() => console.log('fertig'));
async/await
Eine async-Funktion gibt immer ein Promise zurück. await hält die Funktion an, bis das Promise erfüllt ist, und liefert dann dessen Wert. Wird das Promise abgelehnt, wirft await eine Ausnahme, die du mit try/catch abfangen kannst.
const loadUser = async (id) => {
try {
const res = await fetch(`/api/users/${id}`);
if (!res.ok) throw new Error(`HTTP ${res.status}`);
const { name } = await res.json();
return name;
} catch (err) {
console.error('Laden fehlgeschlagen:', err);
throw err;
}
};
Achtung: fetch lehnt bei HTTP-Fehlern wie 404 nicht ab, deshalb musst du res.ok selbst prüfen. await auf oberster Ebene (Top-Level-Await) funktioniert nur in ES-Modulen.
Parallel statt nacheinander
Wenn du unabhängige Aufgaben nacheinander mit await abwartest, verlierst du Zeit. Starte sie stattdessen gemeinsam:
const [user, posts] = await Promise.all([
fetch('/api/user').then((r) => r.json()),
fetch('/api/posts').then((r) => r.json()),
]);
Promise.all: wird beim ersten Fehler abgelehnt.Promise.allSettled: wartet auf alle Promises und liefert für jedes Status und Wert bzw. Fehlergrund.Promise.race/Promise.any: liefert das erste abgeschlossene bzw. das erste erfolgreiche Ergebnis.
Fallstricke
awaitinnerhalb vonforEachwartet nicht. Nutzefor...ofoderPromise.allmitmap.- Ohne
awaitbekommst du ein Promise statt des eigentlichen Werts. - Unbehandelte Ablehnungen lösen
unhandledrejectionaus. Fange Fehler deshalb immer mitcatchodertry/catchab.