问题:try catch为什么不能捕获未被 await 修饰的异步方法异常
async function throwError() {throw new Error("自定义Error!")
}let testOne = async () => {console.debug("start testOne")try {throwError()} catch (e) {console.error("testOne 异常捕获")console.error(e)}
}testOne()let testTwo = async () => {console.debug("start testTwo")try {await throwError()} catch (e) {console.error("testTwo 异常捕获")console.error(e)}
}testTwo()
执行结果:
前提一:Promise 的状态以及常用方法
Promise 是一个可以处理异步操作的对象,Promise 包含三个状态;
- pending(待定):初始状态
- fulfilled(已兑现):操作成功
- rejected(已拒绝):操作失败
Promise 的常用三个方法 then() 、catch()、 finally();
其中 then() 是 Promise 被兑现和拒绝时的回调函数,包含两个函数类型参数:
- onFulfilled:Promise 对象被兑现时异步执行的函数。它的返回值将成为 then() 返回的 Promise 对象的兑现值。如果 onFulfilled 不是一个函数,则内部会被替换为一个恒等函数((x) => x)。
- onRejected:Promise 对象被拒绝时异步执行的函数。它的返回值将成为 catch() 返回的 Promise 对象的兑现值。如果 onRejected 不是一个函数,则内部会被替换为一个恒等函数((x) => {throw x})。
其中 catch() 是 Promise 被拒绝时的回调函数,是 .then(undefined, rejected) 的简写形式。
其中finally() 是 Promise 被兑现或者拒绝之后执行的回调函数,可以用来处理一些在 then 和 catch中执行的重复性代码。
PS:如果一个被拒绝的 Promise 没有实现拒绝事件处理器(then()、catch()、finally()),则这个事件将会由环境来进行处理,比如浏览器等。
前提二:async 关键字
async 关键字用来修饰一个异步方法,异步方法中可以使用 await 关键字
前提三:await 关键字
await 操作符用于等待一个 Promise 兑现并获取它兑现之后的值。
结论
调用异步方法在没有使用 await 修饰的情况下 Promise 的结果没有被等待且给到当前的函数,这样 try catch 也无法捕获异常了。如果 Promise 实现了拒绝事件处理器,则这个事件转交由 Promise 的拒绝事件处理器处理了,那么 try catch 依然无法捕获这个异常。