promise catch:如何知道错误是来自promise拒绝还是来自then语句



想象一个函数返回一个promise(例如从fetch获取API(:

fetch(...)
.then((response) => {...})
.catch((error) => {...});

我如何知道catch语句中的错误是否是由于承诺拒绝而不是then语句中的代码引起的?

以下内容将起作用:

let success = false;
fetch(...)
.then((response) => {success = true; ...})
.catch((error) => {if(success) ...});

但我想知道是否有更好或更本土的方法来做这件事。我也尝试过做一些类似的事情:

fetch(...)
.catch((promiseError) => {...});
.then((response) => {...})
.catch((thenError) => {...});

但我认为它不起作用,因为response没有转发到then语句(或者至少TS是这么说的(。

哪种方式更好?

then接受两个参数:一个函数在实现时调用,另一个函数则在拒绝时调用。因此,您可以更早地处理初始拒绝:

fetch(/*...*/)
.then(
// Fulfillment handler
(response) => {
/*...*/
},
// Rejection handler for `fetch` promise
(error) => {
/*...*/
}
)
.catch((error) => {
// This rejection handler only sees errors not handled above
});

第一个拒绝处理程序(在then调用中(仅用于拒绝来自fetch的承诺,而不是由履行处理程序中的错误引起的拒绝。

第二个拒绝处理程序(在catch调用中(被调用,用于由之前的处理程序的错误(或被拒绝的承诺(引起的拒绝(履行或拒绝(;如果原始promise被拒绝,它不会被调用(但如果第一个拒绝处理程序抛出错误或返回被拒绝的promise,它很可能会被调用(。

因此,在那些你关心的情况下,你可以更接近源头地处理它。

请注意所有没有抛出错误或返回被拒绝/将被拒绝的承诺的拒绝处理程序都会将拒绝(原始承诺(转换为实现(then/catch中的承诺(。这可能对下游then处理程序很重要。


理解这一点的关键是记住then(及其包装catchfinally(返回一个新的promise。这就是为什么:

aPromise.then(onFulfilled).catch(onRejected);

与不同

aPromise.then(onFulfilled, onRejected);

第一个将履行处理程序挂接到aPromise,然后将拒绝处理程序挂接到承诺then返回(这意味着如果aPromise拒绝,则调用拒绝处理程序;如果履行处理程序抛出错误或返回拒绝的承诺,则调用(。相反,第二个只挂接aPromise上的处理程序,因此来自履行处理程序的错误/拒绝不会触发拒绝处理程序。


事实上,.catch(fn)只是.then(undefined, fn)的包装器。:-(规范链接

如果传递给then的函数返回promise,

promise
.then(
(async (response)=>{
...
}).catch((errorFromThen) => {})
).catch((errorFromPromise) => {})

或者仅仅是

promise
.then(
(response)=>{
try {
...
} catch (errorFromThen) {
...
}
}
).catch((errorFromPromise) => {})

相关内容

  • 没有找到相关文章

最新更新