原文: https://codeburst.io/promise-error-handling-in-depth-90b0965149c0
在之前的一篇博文中(https://codeburst.io/everything-you-should-know-about-promise-a05a20bf4c53)我们讨论了Promise的基础知识,也简要的提及了应该如何正确处理错误。但其过于基础,并未论述 Promise 使用者会在开发中遇到的一般问题。
所以,让我们稍微花点时间来深挖 Promise 中的错误处理问题,并找出答案。
本文面向那些寻求答案的人,并用 Q 和 A 表示问答。
Q1: 什么会引发 catch?
A1: 当一个 promise 被 reject,就会引发 catch。典型的情况是,调用 reject(reason) 方法。
除此之外,另有3种情况也会引发 reject。
第一种是开发者的失误:
对于程序中的 bug,就应该通过改变编码来避免;程序永远无法正确处置(因为根据定义,存疑的代码注定会崩坏)。
function asyncTask(url) {
return new Promise((resolve, reject) => {
a.push(1);
if (url) {
return setTimeout(() => {
resolve({
id: 1
});
}, 500);
}
reject({
error: 'url missing in async task 1'
});
});
}
asyncTask('google.com').catch(err => console.log(err)); //ReferenceError: a is not defined复制代码第二种情况是,明确用 throw 抛出错误也会达到同样的效果:
function asyncTask(url) {
return new Promise((resolve, reject) => {
if (url) {
throw new Error('terminate now');
return setTimeout(() => {
resolve({
id: 1
});
}, 500);
}
reject({
error: 'url missing in async task 1'
});
});
}
asyncTask('google.com').catch(err => console.log(err)); //Error: terminate now复制代码最后,嵌套的 promise 也会引发 reject。内层 promise 造成的 reject 状态会冒泡,造成顶层 promise 也 reject:
function asyncTask(url) {
return new Promise((resolve, reject) => {
if (url) {
return setTimeout(() => {
resolve(asyncTask2());
}, 500);
}
reject({
error: 'url missing in async task 1'
});
});
}
function asyncTask2(url) {
return new Promise((resolve, reject) => {
if (url) {
return resolve({
id:2
});
}
reject({
error: 'url missing in async task 2'
});
});
}
asyncTask('google.com')
.catch(err => {
console.log('failed ', err); // { error: 'url missing in async task 2' }
return err;
});复制代码总而言之,以下3种情况会引发 promise 的 reject:
- 开发者在 promise 构造器函数中的错误(bug)
- 明确抛出错误
- 嵌套 promise 的 reject
Q2: catch 监控什么区域呢?
只需要记住 -- catch 会检查 promise 链上位于它之前的每个地方(then 和其他异步操作);如果它之前还有另一个 catch,则从那个 catch 之后的位置开始。
asyncTask()
.then()
.then()
.then()
.catch() // 覆盖 asyncTask 和3个 then复制代码asyncTask()
.catch() // 只覆盖 asyncTask
.then()
.then()
.catch() // 覆盖了2个 then复制代码需要注意的就是,和 then 一样, catch 也会返回一个可链式操作的新 promise 对象。
A3: Yes, you can. 在 catch 中抛出的错误会被下一个 catch 捕获.
asyncTask()
.then()
.then()
.catch(err => {throw new Error('operation failed')})
.catch(err => console.log(err)) // operation failed复制代码promise 中的错误处理有可能会很难缠。希望对此不甚明了的人能从本文获益。
-------------------------------------
长按二维码或搜索 fewelife 关注我们哦
本文详细探讨了JavaScript中Promise的错误处理机制,包括引发catch的原因、catch的作用范围以及在catch中抛出错误的影响。
3116

被折叠的 条评论
为什么被折叠?



