Promise.prototype.finally()
Baseline
Weitgehend verfügbar
Diese Funktion ist gut etabliert und funktioniert auf vielen Geräten und in vielen Browserversionen. Sie ist seit Oktober 2018 browserübergreifend verfügbar.
Die Methode finally() von Promise-Instanzen plant die Ausführung einer Funktion ein, sobald das Promise abgeschlossen ist (entweder erfüllt oder abgelehnt). Sie gibt sofort ein weiteres Promise-Objekt zurück, sodass Sie Aufrufe anderer Promise-Methoden verketten können.
Wie der finally-Block ist diese Methode in der Regel für Aufräumarbeiten gedacht, unabhängig vom Ergebnis des Promise. So müssen Sie Code nicht sowohl im then()- als auch im catch()-Handler des Promise wiederholen.
Probieren Sie es aus
function checkMail() {
return new Promise((resolve, reject) => {
if (Math.random() > 0.5) {
resolve("Mail has arrived");
} else {
reject(new Error("Failed to arrive"));
}
});
}
checkMail()
.then((mail) => {
console.log(mail);
})
.catch((err) => {
console.error(err);
})
.finally(() => {
console.log("Experiment completed");
});
Syntax
promiseInstance.finally(onFinally)
Parameter
onFinally-
Eine Funktion, die asynchron ausgeführt wird, sobald dieses Promise abgeschlossen ist. Gibt die Funktion ein Promise zurück, wartet das resultierende Promise, bis dieses Promise abgeschlossen ist, bevor es fortfährt. Wird das zurückgegebene Promise abgelehnt, wird das resultierende Promise mit demselben Grund abgelehnt. Jeder andere Rückgabewert sowie der Erfüllungswert des zurückgegebenen Promise werden ignoriert.
Rückgabewert
Gibt sofort ein neues Promise zurück. Dieses neue Promise ist zum Zeitpunkt der Rückgabe immer noch ausstehend, unabhängig vom Zustand des aktuellen Promise. Löst onFinally einen Fehler aus oder gibt es ein abgelehntes Promise zurück, wird das neue Promise mit diesem Wert abgelehnt. Andernfalls nimmt das neue Promise denselben Endzustand wie das aktuelle Promise an.
Beschreibung
Die Methode finally() ist nützlich, wenn Sie nach Abschluss eines Promise Verarbeitungsschritte oder Aufräumarbeiten durchführen möchten, unabhängig von dessen Ergebnis.
Die Methode finally() ist dem Aufruf von then(onFinally, onFinally) sehr ähnlich. Es gibt jedoch einige Unterschiede:
- Wenn Sie eine Funktion direkt an dieser Stelle erstellen, müssen Sie sie nur einmal übergeben, statt sie zweimal anzugeben oder eine Variable dafür anzulegen.
- Der
onFinally-Callback erhält kein Argument. Er ist genau für Fälle gedacht, in denen der Ablehnungsgrund oder der Erfüllungswert keine Rolle spielt und daher nicht übergeben werden muss. - Ein
finally()-Aufruf ist normalerweise transparent und spiegelt den endgültigen Zustand des ursprünglichen Promise wider. Zum Beispiel:- Anders als
Promise.resolve(2).then(() => 77, () => 77), das ein Promise zurückgibt, das schließlich mit dem Wert77erfüllt wird, gibtPromise.resolve(2).finally(() => 77)ein Promise zurück, das schließlich mit dem Wert2erfüllt wird. - Ebenso gibt
Promise.reject(3).then(() => 88, () => 88)ein Promise zurück, das schließlich mit dem Wert88erfüllt wird.Promise.reject(3).finally(() => 88)gibt dagegen ein Promise zurück, das schließlich mit dem Grund3abgelehnt wird.
- Anders als
Hinweis:
Ein throw im finally-Callback (oder die Rückgabe eines abgelehnten Promise) führt dennoch dazu, dass das zurückgegebene Promise abgelehnt wird. Beispielsweise werden die von Promise.reject(3).finally(() => { throw 99; }) und Promise.reject(3).finally(() => Promise.reject(99)) zurückgegebenen Promises beide mit dem Grund 99 abgelehnt.
Wie catch() ruft finally() intern die Methode then auf dem Objekt auf, auf dem es selbst aufgerufen wurde. Wenn onFinally keine Funktion ist, wird then() mit onFinally als beiden Argumenten aufgerufen. Bei Promise.prototype.then() bedeutet das, dass kein wirksamer Handler angehängt wird. Andernfalls wird then() mit zwei intern erstellten Funktionen aufgerufen, die sich wie folgt verhalten:
Warnung: Dies dient nur zur Veranschaulichung und ist kein Polyfill.
promise.then(
(value) => Promise.resolve(onFinally()).then(() => value),
(reason) =>
Promise.resolve(onFinally()).then(() => {
throw reason;
}),
);
Da finally() die Methode then() aufruft, unterstützt es Unterklassen. Beachten Sie außerdem den obigen Aufruf von Promise.resolve(): Tatsächlich wird der Rückgabewert von onFinally() mit demselben Algorithmus wie bei Promise.resolve() verarbeitet. Als Konstruktor für das dabei erzeugte Promise wird jedoch der Konstruktor der Unterklasse verwendet. finally() erhält diesen Konstruktor über promise.constructor[Symbol.species].
Beispiele
>finally() verwenden
let isLoading = true;
fetch(myRequest)
.then((response) => {
const contentType = response.headers.get("content-type");
if (contentType && contentType.includes("application/json")) {
return response.json();
}
throw new TypeError("Oops, we haven't got JSON!");
})
.then((json) => {
/* process your JSON further */
})
.catch((error) => {
console.error(error); // this line can also throw, e.g. when console = {}
})
.finally(() => {
isLoading = false;
});
Spezifikationen
| Spezifikation |
|---|
| ECMAScript® 2027 Language Specification> # sec-promise.prototype.finally> |