Promise的catch()和then(...,err)的优先级
对于
Promise
如果你看过ES6的教程,应该就已经有所了解了。在
Promise
的回调中
then(...,err)
和
catch()
都是用来处理返回的错误的,那么这俩在实际应用上的执行顺序是怎样的呢,我个人做了点小测试。有兴趣的大家可以继续阅读本章,也可以提出你的想法。我会多做补充的。
创建Promise的测试函数
将Promise
封装到一个test
函数中,通过传值控制Promise
返回的状态。
function test(arg) {
const p = new Promise((resolve, reject) => {
if (arg) {
resolve(`result is ${arg}`);
} else if (arg === 0) {
throw new Error("result is 0");
} else {
reject("result is null");
}
});
return p;
}
then中没有err时
then
中没有创建失败时的回调。
// reject返回失败
test()
.then((result) => {
console.log(`success: ${result}`);
})
.catch((err) => {
console.error(`catch: ${err}`);
});
// 通过抛出异常返回失败
test(0)
.then((result) => {
console.log(`success: ${result}`);
})
.catch((err) => {
console.error(`catch: ${err}`);
});
输出的结果为:
catch: result is null
catch: Error: result is 0
由此可见,在then
没有对失败进行处理的情况下,由catch
处理所有失败的回调。
then中有err时
then
中创建了失败的回调。
then在catch之前
// reject返回失败
test()
.then(
(result) => {
console.log(`success: ${result}`);
},
(err) => {
console.log(`err: ${err}`);
}
)
.catch((err) => {
console.error(`catch: ${err}`);
});
// 通过异常或主动抛出异常返回失败
test(0)
.then(
(result) => {
console.log(`success: ${result}`);
},
(err) => {
console.log(`err: ${err}`);
}
)
.catch((err) => {
console.error(`catch: ${err}`);
});
输出的结果为:
err: result is null
err: Error: result is 0
由此可见,在then
有对失败进行处理的情况下,且then
在catch
之前时,由then
捕获所有失败的回调。
then在catch之后
// reject返回失败
test()
.catch((err) => {
console.error(`catch: ${err}`);
})
.then(
(result) => {
console.log(`success: ${result}`);
},
(err) => {
console.log(`err: ${err}`);
}
);
// 通过异常或主动抛出异常返回失败
test(0)
.catch((err) => {
console.error(`catch: ${err}`);
})
.then(
(result) => {
console.log(`success: ${result}`);
},
(err) => {
console.log(`err: ${err}`);
}
);
输出的结果为:
catch: result is null
catch: Error: result is 0
success: undefined
success: undefined
由此可见,在then
有对失败进行处理的情况下,且then
在catch
之后时,由catch
处理所有失败的回调。
catch
处理之后依然会触发Promise
的then
的成功的回调方法。
什么时候只有catch可以奏效呢?
答:只有当Promise
的then
中的回调方法有错误的时候。
catch在then之后
// reject返回失败
test()
.then(
(result) => {
console.log(successArg);
console.log(`success: ${result}`);
},
(err) => {
console.log(failArg);
console.log(`err: ${err}`);
}
)
.catch((err) => {
console.error(`catch: ${err}`);
});
// resolve返回成功
test(1)
.then(
(result) => {
console.log(successArg);
console.log(`success: ${result}`);
},
(err) => {
console.log(failArg);
console.log(`err: ${err}`);
}
)
.catch((err) => {
console.error(`catch: ${err}`);
});
输出的结果为:
catch: ReferenceError: failArg is not defined
catch: ReferenceError: successArg is not defined
由上可知,谁运行了谁报错,而回调方法的错误,由catch
进行处理。
catch在then之前
如果catch
在then
前面呢?
// reject返回失败
test()
.catch((err) => {
console.error(`catch: ${err}`);
})
.then(
(result) => {
console.log(successArg);
console.log(`success: ${result}`);
},
(err) => {
console.log(failArg);
console.log(`err: ${err}`);
}
);
// resolve返回成功
test(1)
.catch((err) => {
console.error(`catch: ${err}`);
})
.then(
(result) => {
console.log(successArg);
console.log(`success: ${result}`);
},
(err) => {
console.log(failArg);
console.log(`err: ${err}`);
}
);
输出结果为:
catch: result is null
(node:8149) UnhandledPromiseRejectionWarning: ReferenceError: successArg is not defined
由上可知,如果catch
在then
之前,then
的回调错误依然是由catch
进行处理,但是由于then
中的成功的回调方法依然会被执行,所以程序会由于错误被中断。
总结
感谢阅读,如有讨论欢迎留言。