这是我参与8月更文挑战的第7天,活动详情查看: 8月更文挑战
前言
最近写快应用,有个数据格式转化的问题。为了防止后端数据出错,就加了个try...catch来错误捕获。结果发现有些情况明明数据出问题了,却没有将异常抛出来,后来仔细分析了下,原来因为代码在报错的时候,try...catch已经执行完了。这篇文章就来整理下try...catch的具体用法。
try...catch
首先来看下try...catch的作用:
try...catch能捕获的异常必须是线程执行进入到try...catch且try...catch未执行完的时候抛出来。
1. 进入之前
语法异常在语法检查阶段就报错了,线程尚未进入try...catch代码块,所以无法捕获到异常。
try {
a.
}catch(e) {
console.log('error-------', e);
}
// 执行结果:
VM483:3 Uncaught SyntaxError: Unexpected token '}'
2. 进入之中
代码报错的时候,线程处于try...catch之中,能够捕获到异常。
try {
a.b
}catch(e) {
console.log('error-------', e);
}
VM488:4 error------- ReferenceError: a is not defined
3. 进入之后
代码报错的时候,线程已经执行完try...catch,这种无法捕获异常。
try {
setTimeout(() => {
a.b = 1;
}, 1000)
}catch(e) {
console.log('error---------', e);
}
// 执行结果:
VM544:3 Uncaught ReferenceError: a is not defined
try...catch无法捕获异步代码中抛出的错误,如果要捕获则应该将try...catch代码写到异步代码内部。
setTimeout(() => {
try{
a.b = 1;
}catch(e) {
console.log('error---------', e);
}
}, 1000)
// 执行结果:
error--------- ReferenceError: a is not defined at <anonymous>:3:9
4. Promise的异常
线程在执行a.b的时候,try...catch也在同步执行。为啥也没捕获到异常??
Promise在执行的时候,函数代码周围都是有个隐式的try...catch包裹的,所有的同步异常都会被内部捕获到,但是并不会往上抛异常。所以我们写的try...catch并不会捕获到。
try{
new Promise(function (resolve, reject) {
a.b;
}).then(v=>{
console.log(v);
});
}catch(e){
console.log('error---------------',e);
}
// 执行结果:
Promise {<rejected>: ReferenceError: a is not defined
at <anonymous>:3:9
at new Promise (<anonymous>)
at <an…}__proto__: Promise[[PromiseState]]: "rejected"[[PromiseResult]]: ReferenceError: a is not defined
at <anonymous>:3:9
at new Promise (<anonymous>)
at <anonymous>:2:5
VM552:3 Uncaught (in promise) ReferenceError: a is not defined
at <anonymous>:3:9
5. async...await异常
如何用try...catch去捕获async...await的错误呢??
是不是像Promise那样直接写在async最外层??
try{
async function f1() {
await Promise.reject(new Error('await错误'));
}
f1();
}catch(e) {
console.log(111, e)
}
结果:
将try...catch写在async函数最外层并不能捕获async...await的异常,而是会走到Promise的异常抛出。
那如果将try...catch写在await呢??
async function f2() {
try{
await Promise.reject(new Error('await出错'));
}catch(e) {
console.log(111, e);
}
}
f2();
//执行结果:
111 Error: await出错 at f2 (<anonymous>:3:30)
async...await捕获异常,需要将await函数写在try...catch中。