Dieser Inhalt wurde automatisch aus dem Englischen übersetzt, und kann Fehler enthalten. Erfahre mehr über dieses Experiment.

View in English Always switch to English

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

js
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 Wert 77 erfüllt wird, gibt Promise.resolve(2).finally(() => 77) ein Promise zurück, das schließlich mit dem Wert 2 erfüllt wird.
    • Ebenso gibt Promise.reject(3).then(() => 88, () => 88) ein Promise zurück, das schließlich mit dem Wert 88 erfüllt wird. Promise.reject(3).finally(() => 88) gibt dagegen ein Promise zurück, das schließlich mit dem Grund 3 abgelehnt wird.

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.

js
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

js
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

Browser-Kompatibilität

Siehe auch