Asynchrones JavaScript: Promises verstehen
Promises sind der moderne Weg, um asynchrone Aufgaben in JavaScript zu verwalten. Lerne, wie sie funktionieren und Callback-Chaos vermeiden.
JavaScript erledigt viele Dinge, die Zeit brauchen: Daten von einem Server laden, eine Datei lesen oder auf einen Timer warten. Solche Aufgaben sind asynchron, dein Code wartet nicht einfach, sondern läuft weiter. Um das Ergebnis später sauber zu verarbeiten, gibt es Promises. In diesem Beitrag verstehst du, was ein Promise ist und wie du damit arbeitest.
Warum überhaupt asynchron?
JavaScript läuft in einem einzigen Thread. Würde es bei jedem Datenabruf einfach stehen bleiben, würde die ganze Seite einfrieren. Stattdessen startet es die Aufgabe und arbeitet weiter. Sobald das Ergebnis da ist, wird dein Code benachrichtigt. Genau das organisiert ein Promise.
Was ist ein Promise?
Ein Promise ist ein Platzhalter für ein Ergebnis, das es jetzt noch nicht gibt, aber in Zukunft geben wird. Es hat drei Zustände: pending (wartend), fulfilled (erfolgreich erfüllt) und rejected (fehlgeschlagen). Ein Promise wechselt genau einmal vom Wartezustand in einen der beiden Endzustände.
const versprechen = new Promise((resolve, reject) => {
const erfolg = true;
if (erfolg) {
resolve("Alles hat geklappt!");
} else {
reject("Etwas ist schiefgelaufen.");
}
});Mit resolve meldest du Erfolg, mit reject einen Fehler. In der Praxis erstellst du selten eigene Promises, sondern bekommst sie von Funktionen wie fetch geliefert.
Auf das Ergebnis reagieren: then und catch
Um an das Ergebnis eines Promise zu kommen, hängst du then an. Die übergebene Funktion läuft, sobald das Promise erfüllt ist. Für Fehler gibt es catch.
versprechen
.then((ergebnis) => {
console.log("Erfolg:", ergebnis);
})
.catch((fehler) => {
console.log("Fehler:", fehler);
});So trennst du sauber den Erfolgsfall vom Fehlerfall. Der Code in then läuft erst, wenn das Ergebnis wirklich vorliegt.
Ein praktisches Beispiel mit Verzögerung
Stell dir vor, du wartest zwei Sekunden, bevor du eine Nachricht ausgibst. Mit einem Promise und setTimeout sieht das so aus:
function warte(sekunden) {
return new Promise((resolve) => {
setTimeout(() => {
resolve("Fertig nach " + sekunden + " Sekunden");
}, sekunden * 1000);
});
}
warte(2).then((nachricht) => {
console.log(nachricht); // Nach 2 Sekunden: Fertig nach 2 Sekunden
});Promises verketten
Der große Vorteil: Da then wieder ein Promise zurückgibt, kannst du mehrere Schritte hintereinander schalten. Das ersetzt die früher gefürchtete tief verschachtelte Callback-Pyramide.
warte(1)
.then((nachricht) => {
console.log("Schritt 1:", nachricht);
return warte(1); // nächstes Promise zurückgeben
})
.then((nachricht) => {
console.log("Schritt 2:", nachricht);
});Jeder then-Block wartet auf den vorherigen. So bleibt der Ablauf lesbar und von oben nach unten verständlich.
Fazit
Promises sind das Fundament für sauberes asynchrones JavaScript. Sie repräsentieren ein zukünftiges Ergebnis mit den Zuständen pending, fulfilled und rejected. Mit then reagierst du auf Erfolg, mit catch auf Fehler, und durch Verkettung baust du klare Abläufe. Wenn du Promises verstanden hast, ist der nächste Schritt zu async und await ganz leicht, denn die bauen genau darauf auf.