Start · Sprachen · JavaScript · Kapitel · Asynchronität (Promises, async/await)
// Kapitel · JavaScript

Asynchronität (Promises, async/await)

Diese Sektion erklärt, wie JavaScript mit Promises und async/await asynchron arbeitet. Behandelt werden Verkettung, Fehlerbehandlung, parallele Ausführung und typische Fallstricke.

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

  • await innerhalb von forEach wartet nicht. Nutze for...of oder Promise.all mit map.
  • Ohne await bekommst du ein Promise statt des eigentlichen Werts.
  • Unbehandelte Ablehnungen lösen unhandledrejection aus. Fange Fehler deshalb immer mit catch oder try/catch ab.