JavaScript Promise
Bevor Sie dieses Kapitel durcharbeiten, müssen Sie verstehen, was asynchrone Programmierung ist. Sie können sich Folgendes ansehen:Asynchrone Programmierung in JavaScript
Promise ist eine von ECMAScript 6 bereitgestellte Klasse, die entwickelt wurde, um komplexe asynchrone Aufgaben eleganter zu schreiben.
Promise ist ein Objekt in JavaScript, das verwendet wird, um asynchrone Operationen zu behandeln. Es stellt den letztendlichen Abschluss (oder Fehlschlag) einer asynchronen Operation und ihren resultierenden Wert dar.
Einfach ausgedrückt ist ein Promise ein "Versprechen", dass zu einem späteren Zeitpunkt ein Ergebnis zurückgegeben wird (entweder ein erfolgreiches Ergebnis oder ein Grund für das Scheitern).
Ein Promise hat drei Zustände:
- pending: Anfangszustand, weder fulfilled noch rejected
- fulfilled: bedeutet, dass die Operation erfolgreich abgeschlossen wurde
- rejected: bedeutet, dass die Operation fehlgeschlagen ist

Beispiel
// asynchroner Operationscode
if (/* Operation erfolgreich */) {
resolve('Erfolgreiches Ergebnis'); // Promise-Status in erfüllt ändern
} else {
reject('Fehlergrund'); // Promise-Status in abgelehnt ändern
}
});
Browser-Unterstützung
Da Promise in ES6 neu hinzugefügt wurde, unterstützen einige ältere Browser es nicht. Apple Safari 10 und Windows Edge 14 und höher begannen, ES6-Funktionen zu unterstützen.
Das Folgende zeigt die Browser-Unterstützung für Promise:
| Chrome 58 | Edge 14 | Firefox 54 | Safari 10 | Opera 55 |
Verwendung von Promise
then()-Methode
then()Diese Methode wird verwendet, um Callback-Funktionen anzugeben, wenn der Promise-Zustand auf erfüllt oder abgelehnt wechselt.
Beispiel
(result) => {
// Erfolgsfall behandeln
console.log('Erfolg:', result);
},
(error) => {
// Fehlerfall behandeln
console.error('Fehler:', error);
}
);
catch()-Methode
catch()Diese Methode wird speziell verwendet, um Fälle zu behandeln, in denen das Promise abgelehnt wird.
Beispiel
.then((result) => {
console.log('Erfolg:', result);
})
.catch((error) => {
console.error('Fehler:', error);
});
finally()-Methode
finally()Diese Methode wird unabhängig vom endgültigen Zustand des Promise ausgeführt.
Beispiel
.then((result) => {
console.log('Erfolg:', result);
})
.catch((error) => {
console.error('Fehler:', error);
})
.finally(() => {
console.log('Operation abgeschlossen');
});
Promise-Verkettung
Eine leistungsstarke Eigenschaft von Promise ist, dass mehrere asynchrone Operationen verkettet werden können.
Beispiel
.then((result) => doSecondThing(result))
.then((newResult) => doThirdThing(newResult))
.then((finalResult) => {
console.log('Endergebnis:', finalResult);
})
.catch((error) => {
console.error('Fehler irgendwo in der Kette:', error);
});
Statische Promise-Methoden
Promise.all()
Warte, bis alle Promises abgeschlossen sind oder bis ein beliebiges Promise fehlschlägt.
Beispiel
.then((results) => {
// results ist ein Array, das alle Promise-Ergebnisse enthält
console.log(results);
})
.catch((error) => {
// Wird hier ausgeführt, wenn irgendein Promise fehlschlägt
console.error(error);
});
Promise.race()
Gibt das Ergebnis des ersten Promise zurück, das abgeschlossen wird (unabhängig von Erfolg oder Fehlschlag).
Beispiel
.then((result) => {
// Nutze das Ergebnis des ersten abgeschlossenen Promises
console.log(result);
})
.catch((error) => {
// Wenn das erste abgeschlossene Promise abgelehnt wird
console.error(error);
});
Promise.resolve() und Promise.reject()
Schnell ein erfülltes oder abgelehntes Promise erstellen.
Beispiel
const rejectedPromise = Promise.reject('Immediately rejected reason');
Praktische Anwendungsbeispiele
Beispiel 1: Verwenden von Promise zum Verarbeiten von AJAX-Anfragen
Beispiel
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.open('GET', url);
xhr.onload = () => {
if (xhr.status === 200) {
resolve(xhr.response);
} else {
reject(new Error(xhr.statusText));
}
};
xhr.onerror = () => reject(new Error('Netzwerkfehler'));
xhr.send();
});
}
fetchData('https://api.example.com/data')
.then((data) => {
console.log('Daten erfolgreich abgerufen:', data);
})
.catch((error) => {
console.error('Fehler beim Abrufen der Daten:', error);
});
Beispiel 2: Verwenden einer Promise-Kette zum Verarbeiten mehrerer asynchroner Operationen
Beispiel
return fetch(`/users/${userId}`);
}
function getPosts(userId) {
return fetch(`/users/${userId}/posts`);
}
getUser(123)
.then((user) => {
console.log('Benutzerinformationen werden abgerufen:', user);
return getPosts(user.id);
})
.then((posts) => {
console.log('Benutzerbeiträge werden abgerufen:', posts);
})
.catch((error) => {
console.error('Vorgang fehlgeschlagen:', error);
});
Häufige Probleme und bewährte Verfahren
1. Promise-Verschachtelung vermeiden
Falscher Ansatz (die Promise-Version der Callback-Hölle):
Beispiel
doSecondThing(firstResult).then((secondResult) => {
doThirdThing(secondResult).then((thirdResult) => {
console.log(thirdResult);
});
});
});
Richtiger Ansatz (Verkettung verwenden):
Beispiel
.then(doSecondThing)
.then(doThirdThing)
.then((finalResult) => {
console.log(finalResult);
});
2. Ablehnungen immer behandeln
Wenn du vergisst, Promise-Ablehnungen zu behandeln, führt das zu Fehlern vom Typ "uncaught promise rejection". Verwende immer.catch()odertry/catch(bei async/await), um Fehler zu behandeln.
3. Promises sind nicht abbrechbar
Sobald ein Promise erstellt wurde, kann es nicht abgebrochen werden. Wenn du eine Abbruchfunktion benötigst, ziehe die Verwendung von AbortController oder anderen Mustern in Betracht.
4. FAQ
F: Kann die Reihenfolge von then, catch und finally umgekehrt werden?
A: Ja, der Effekt ist genau derselbe. Aber es wird nicht empfohlen; am besten schreibt man das Programm in der Reihenfolge then-catch-finally.
F: Können außer dem then-Block die anderen beiden Blöcke mehrfach verwendet werden?
A: Ja. finally wird, wie then, der Reihe nach ausgeführt, aber nur der erste catch-Block wird ausgeführt, es sei denn, im catch-Block tritt eine Ausnahme auf. Daher ist es am besten, nur einen catch- und einen finally-Block vorzusehen.
F: Wie unterbricht man einen then-Block?
A: Ein then-Block wird standardmäßig sequenziell nach unten ausgeführt; return kann ihn nicht unterbrechen. Sie können throw verwenden, um zu catch zu springen, um die Unterbrechung zu erreichen.
F: Wann ist es angemessen, Promise anstelle traditioneller Callback-Funktionen zu verwenden?
A: Wenn mehrere asynchrone Operationen sequenziell ausgeführt werden müssen. Wenn Sie beispielsweise einen Benutzernamen und ein Passwort nacheinander über asynchrone Methoden prüfen möchten, müssen Sie zuerst den Benutzernamen asynchron prüfen und dann das Passwort asynchron prüfen — das ist eine Situation, die sich gut für Promise eignet.
F: Ist Promise eine Methode, um Asynchrones in Synchrones umzuwandeln?
A: Überhaupt nicht. Promise ist nur ein besserer Programmierstil.
F: Wann müssen wir ein weiteres then schreiben, anstatt die Programmierung im aktuellen then fortzusetzen?
A: Wenn Sie eine weitere asynchrone Aufgabe aufrufen müssen.
Promise und async/await
ES2017 führte async/await ein, das auf Promise basiert und eine intuitivere Syntax für die Handhabung asynchroner Operationen bietet.
Beispiel
try {
const user = await getUser(123);
const posts = await getPosts(user.id);
console.log('User posts:', posts);
} catch (error) {
console.error('Fehler beim Abrufen der Daten:', error);
}
}
Obwohl async/await besser lesbar ist, ist das Verständnis der grundlegenden Konzepte von Promise nach wie vor sehr wichtig, denn es ist die Grundlage von async/await.
Andere Erweiterungen