Promise.prototype.catch()
catch()
方法是 Promise
实例的方法,用于安排在 promise 被拒绝时调用的函数。它立即返回另一个 Promise
对象,允许您 链接 到其他 promise 方法的调用。它是 then(undefined, onRejected)
的快捷方式。
试一试
语法
promiseInstance.catch(onRejected)
参数
onRejected
-
当此 promise 被拒绝时异步执行的函数。其返回值成为
catch()
返回的 promise 的完成值。该函数使用以下参数调用reason
-
promise 被拒绝时的值。
返回值
返回一个新的 Promise
。无论当前 promise 的状态如何,此新 promise 在返回时始终处于挂起状态。如果调用了 onRejected
,则返回的 promise 将根据此调用的返回值解析,或拒绝此调用的抛出错误。如果当前 promise 完成,则不会调用 onRejected
,并且返回的 promise 完成到相同的值。
描述
catch
方法用于 promise 组合中的错误处理。由于它返回一个 Promise
,因此它 可以像其姊妹方法 then()
一样链接。
如果 promise 被拒绝,并且没有拒绝处理程序可调用(可以通过 then()
、catch()
或 finally()
中的任何一个附加处理程序),则主机将显示拒绝事件。在浏览器中,这会导致 unhandledrejection
事件。如果处理程序附加到已导致未处理拒绝事件的已拒绝 promise,则会触发另一个 rejectionhandled
事件。
catch()
在内部对调用它的对象调用 then()
,并将 undefined
和 onRejected
作为参数传递。该调用的值将直接返回。如果您包装方法,则可以观察到这一点。
// 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()]
这意味着传递 undefined
仍会导致返回的 promise 被拒绝,并且您必须传递一个函数以防止最终 promise 被拒绝。
由于 catch()
只是调用 then()
,因此它支持子类化。
示例
使用和链接 catch() 方法
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"),
);
抛出错误时的注意事项
抛出错误大多数情况下会调用 catch()
方法
const p1 = new Promise((resolve, reject) => {
throw new Error("Uh-oh!");
});
p1.catch((e) => {
console.error(e); // "Uh-oh!"
});
异步函数内部抛出的错误将像未捕获的错误一样起作用
const p2 = new Promise((resolve, reject) => {
setTimeout(() => {
throw new Error("Uncaught Exception!");
}, 1000);
});
p2.catch((e) => {
console.error(e); // This is never called
});
resolve
调用后抛出的错误将被忽略
const p3 = new Promise((resolve, reject) => {
resolve();
throw new Error("Silenced Exception!");
});
p3.catch((e) => {
console.error(e); // This is never called
});
如果 promise 已完成,则不会调用 catch()
// 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);
},
);
规范
规范 |
---|
ECMAScript 语言规范 # sec-promise.prototype.catch |
浏览器兼容性
BCD 表格仅在启用 JavaScript 的浏览器中加载。