Promise.prototype.catch()

Baseline Widely available

This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.

Die catch()-Methode von Promise-Instanzen plant eine Funktion ein, die aufgerufen wird, wenn das Promise abgelehnt wird. Sie gibt sofort ein weiteres Promise-Objekt zurück, das es Ihnen ermöglicht, Aufrufe anderer Promise-Methoden zu verketten. Es ist eine Abkürzung für then(undefined, onRejected).

Probieren Sie es aus

Syntax

js
promiseInstance.catch(onRejected)

Parameter

onRejected

Eine Funktion, die asynchron ausgeführt wird, wenn dieses Promise abgelehnt wird. Ihr Rückgabewert wird zum Erfüllungswert des von catch() zurückgegebenen Promise. Die Funktion wird mit den folgenden Argumenten aufgerufen:

reason

Der Wert, mit dem das Promise abgelehnt wurde.

Rückgabewert

Gibt ein neues Promise zurück. Dieses neue Promise ist immer ausstehend, wenn es zurückgegeben wird, unabhängig vom Status des aktuellen Promise. Wenn onRejected aufgerufen wird, wird das zurückgegebene Promise basierend auf dem Rückgabewert dieses Aufrufs aufgelöst oder mit dem im Aufruf ausgelösten Fehler abgelehnt. Wenn das aktuelle Promise erfüllt wird, wird onRejected nicht aufgerufen und das zurückgegebene Promise wird auf denselben Wert erfüllt.

Beschreibung

Die catch-Methode wird für die Fehlerbehandlung in der Promise-Komposition verwendet. Da sie ein Promise zurückgibt, kann es verkettet werden auf die gleiche Weise wie seine Schwestermethode then().

Wenn ein Promise abgelehnt wird und es keine Ablehnungshandler zu rufen gibt (ein Handler kann durch eines der then(), catch() oder finally() angehängt werden), wird das Ablehnungsereignis vom Host weitergegeben. Im Browser führt dies zu einem unhandledrejection-Ereignis. Wenn ein Handler an ein abgelehntes Promise angehängt wird, dessen Ablehnung bereits ein unbehandeltes Ablehnungsereignis verursacht hat, wird dann ein weiteres rejectionhandled-Ereignis ausgelöst.

catch() ruft intern then() auf dem Objekt auf, auf dem es aufgerufen wurde, und übergibt undefined und onRejected als Argumente. Der Wert dieses Aufrufs wird direkt zurückgegeben. Dies ist beobachtbar, wenn Sie die Methoden umschließen.

js
// overriding original Promise.prototype.then/catch just to add some logs
((Promise) => {
  const originalThen = Promise.prototype.then;
  const originalCatch = Promise.prototype.catch;

  Promise.prototype.then = function (...args) {
    console.log("Called .then on %o with arguments: %o", this, args);
    return originalThen.apply(this, args);
  };
  Promise.prototype.catch = function (...args) {
    console.error("Called .catch on %o with arguments: %o", this, args);
    return originalCatch.apply(this, args);
  };
})(Promise);

// calling catch on an already resolved promise
Promise.resolve().catch(function XXX() {});

// Logs:
// Called .catch on Promise{} with arguments: Arguments{1} [0: function XXX()]
// Called .then on Promise{} with arguments: Arguments{2} [0: undefined, 1: function XXX()]

Das bedeutet, dass die Übergabe von undefined dazu führt, dass das zurückgegebene Promise weiterhin abgelehnt wird, und Sie müssen eine Funktion übergeben, um zu verhindern, dass das endgültige Promise abgelehnt wird.

Da catch() einfach then() aufruft, unterstützt es die Unterklassenbildung.

Hinweis: Die folgenden Beispiele werfen Instanzen von Error. Wie bei synchronen throw-Anweisungen wird dies als gute Praxis betrachtet; andernfalls müsste der Teil, der das Auffangen durchführt, Überprüfungen durchführen, um zu sehen, ob das Argument ein String oder ein Fehler war, und Sie könnten wertvolle Informationen wie Stack-Traces verlieren.

Beispiele

Verwenden und Verketten der catch()-Methode

js
const p1 = new Promise((resolve, reject) => {
  resolve("Success");
});

p1.then((value) => {
  console.log(value); // "Success!"
  throw new Error("oh, no!");
})
  .catch((e) => {
    console.error(e.message); // "oh, no!"
  })
  .then(
    () => console.log("after a catch the chain is restored"), // "after a catch the chain is restored"
    () => console.log("Not fired due to the catch"),
  );

// The following behaves the same as above
p1.then((value) => {
  console.log(value); // "Success!"
  return Promise.reject("oh, no!");
})
  .catch((e) => {
    console.error(e); // "oh, no!"
  })
  .then(
    () => console.log("after a catch the chain is restored"), // "after a catch the chain is restored"
    () => console.log("Not fired due to the catch"),
  );

Fehler beim Werfen von Fehlern

Das Werfen eines Fehlers ruft die catch()-Methode meistens auf:

js
const p1 = new Promise((resolve, reject) => {
  throw new Error("Uh-oh!");
});

p1.catch((e) => {
  console.error(e); // "Uh-oh!"
});

Fehler, die innerhalb von asynchronen Funktionen geworfen werden, verhalten sich wie nicht aufgefangene Fehler:

js
const p2 = new Promise((resolve, reject) => {
  setTimeout(() => {
    throw new Error("Uncaught Exception!");
  }, 1000);
});

p2.catch((e) => {
  console.error(e); // This is never called
});

Fehler, die nach dem Aufruf von resolve geworfen werden, werden unterdrückt:

js
const p3 = new Promise((resolve, reject) => {
  resolve();
  throw new Error("Silenced Exception!");
});

p3.catch((e) => {
  console.error(e); // This is never called
});

catch() wird nicht aufgerufen, wenn das Promise erfüllt wird

js
// Create a promise which would not call onReject
const p1 = Promise.resolve("calling next");

const p2 = p1.catch((reason) => {
  // This is never called
  console.error("catch p1!");
  console.error(reason);
});

p2.then(
  (value) => {
    console.log("next promise's onFulfilled");
    console.log(value); // calling next
  },
  (reason) => {
    console.log("next promise's onRejected");
    console.log(reason);
  },
);

Spezifikationen

Specification
ECMAScript Language Specification
# sec-promise.prototype.catch

Browser-Kompatibilität

BCD tables only load in the browser

Siehe auch