-
Notifications
You must be signed in to change notification settings - Fork 0
Open
Description
简单的 try catch
通常处理错误一般通过 try catch
去进行处理, 下面先来看一个简单的例子
function thisThrows() {
throw new Error("Thrown from thisThorws()");
}
try {
thisThrows();
} catch (e) {
console.log(e); // (1)正常打印
} finally {
console.log("We do cleanup here"); //(2) We do cleanup here
}
上面按照预期进行打印输出:
output:
Error: Thrown from thisThorws()
We do cleanup here
使用 try catch 处理 Promise Rejecting
下面修改 thisThrows
函数, 如下:
async function thisThrows() {
throw new Error("Thrown from thisThrows()");
}
try {
thisThrows();
} catch (error) {
console.log(e); // 不会打印
} finally {
console.log("We do cleanup here"); // (1)正常打印
}
上面thisThrows
变成了异步函数, 通过 async 修饰的函数, 其会返回 Promise .
在 async
函数中有如下几种情况:
- 当没有显示定义返回语句. 它相当于返回了一个
resolving promise
. 等价于return Promise.Resolve()
- 当返回一个值, 它将返回
resolving promise
其 resolve 的值为其返回值, 等价于return Promise.Resolve("My return String")
- 当抛出一个
error
时, 将基于error
返回一个rejected promised
. 等价于return Promise.reject(error)
上面输出如下:
output:
We do cleanup here
Uncaught (in promise) Error: Thrown from thisThrows()
从结果来看并没有被try catch
捕获, 为什么? try catch
只能捕获同步到代码.
其实我们有两种方式可以解决上面的问题:
- 通过
await
的方式去调用thisThrows
- 通过
.catch()
方式
第一种方式:
async function thisThrows() {
throw new Error("Thrown from thisThrows()");
}
async function run() {
try {
await thisThrows();
} catch (error) {
console.log(error); //(1) 打印
} finally {
console.log("We do cleanup here"); // (2)正常打印
}
}
run();
上面输出如下:
Output:
Error: Thrown from thisThrows()
We do cleanup here
第二种方式:
async function thisThrows() {
throw new Error("Thrown from thisThrows()");
}
thisThrows()
.catch(console.error)
.then(() => console.log("We do cleanup here"));
上面输出如下:
Output:
Error: Thrown from thisThrows()
We do cleanup here
稍微复杂的案例
async function thisThrows() {
throw new Error("Thrown from thisThrows()");
}
async function myFunctionThatCatches() {
try {
return thisThrows();
} catch (e) {
console.error(e);
} finally {
console.log("We do cleanup here");
}
return "Nothing found";
}
async function run() {
const myValue = await myFunctionThatCatches();
console.log(myValue);
}
上面从 async
函数中返回 thisThrows
, 看看会输出什么?
预期的输出:
We do cleanup here
Nothing found
实际的输出:
We do cleanup here
Uncaught (in promise) Error: Thrown from thisThrows()
为什么?
下面分析下执行步骤:
- 首先
thisThrows()
是一个 async 方法, 且内部抛出一个错误 - 当
thisThrows()
被执行时, 它会返回状态为 ``rejected 的 Promise 对象 A. - 该 A 对象作为
myFunctionThatCatches
函数的返回值 await
发现 A 对象为rejected
状态,则会向外抛出该错误- 同样 console.log(myValue) 并不会执行
同样前面提到 try catch
语句并不能捕获异步错误, 所以其并不会进入 catch
中, 但 finally
不管情况都会被执行.
如果想按照预期的输出, 可以做如下的修改:
async function thisThrows() {
throw new Error("Thrown from thisThrows()");
}
async function myFunctionThatCatches() {
try {
return await thisThrows();
} catch (e) {
console.error(e);
} finally {
console.log("We do cleanup here");
}
return "Nothing found";
}
async function run() {
const myValue = await myFunctionThatCatches();
console.log(myValue);
}
上面输出结果为:
Output:
Error: Thrown from thisThrows()
We do clearnup here
Nothing found
重置 error stack trace
有时我们想具化到特定错误,可能会在 catch
中重新返回新的错误对象, 就像下面这样:
async function thisThrows() {
throw new Error("Thrown from thisThrows()");
}
async function myFunctionThatCatches() {
try {
return await thisThrows();
} catch (e) {
throw new TypeError(e.message);
} finally {
console.log("We do cleanup here");
}
return "Nothing found";
}
async function run() {
const myValue = await myFunctionThatCatches();
console.log(myValue);
}
上面输出如下:
Output:
VM569:8 Uncaught (in promise) TypeError: Thrown from thisThrows()
at myFunctionThatCatches (<anonymous>:8:17)
at async run (<anonymous>:16:25)
从上面的结果来看, 错误原因没有被修改, 但细心的会发现一个错误栈被重写. 上面看到错误发生是在 myFunctionThatCatches
中, 其实真正错误是在 thisThrows
中.
当我们去重写错误栈的时, 需要去注意.
总结
try catch
语句只能捕获同步错误- 可以通过
try catch + async
函数处理异步错误 - 可以通过
.catch()
处理异步错误
wangjing013 and nitrogewangjing013wangjing013wangjing013wangjing013
Metadata
Metadata
Assignees
Labels
No labels