try catch 捕获和处理异常的机制

219 阅读2分钟

try catch是JavaScript处理错误的一种重要机制。try块中包含可能出错的代码,catch块处理try块中的错误。try catch 主要的作用:在程序运行过程中代码报错不会导致整个程序崩溃,报错得到及时处理。

try {
    // 可能出错的逻辑代码
} catch (error) {
    // 出错时处理的代码
}

细节注意:

1. 当try块中代码出错时,则出错后面的代码不会执行,会触发catch来捕获这个错误

2. try块正常运行时,catch块不会执行

3. 不管程序是否报错,finally块都会执行

try {
    let str = '巧巧'
    console.log(arr) // arr is not defined  后面代码不会执行
    console.log(str) 
} catch (e) {
    // try块中报错
    console.log(e)
}

try {
    let num = 0;
    console.log(num)
} catch (e) {
    // try块正常 catch里不会执行
    console.log(e)
}

catch块中接收一个Error对象,对象包含了名称,消息,堆栈信息。

try {
    fun();
} catch(e){
    // 错误对象
    const { name, message, stack } = e
} finally {
    // 都会执行
}

Error对象里e.name值对应的错误信息,针对不同的错误进行不同的处理。

ReferenceError: 非法或不能识别的引用
EvalError: eval()使用不正确
RangeError: 数值越界
SyntaxError: 发生语法解析错误
TypeError: 类型错误
URIError: URI处理函数使用错误

下面我们一起来探索下try catch的用法

1. 捕获特定类型的异常

try {
    // 可能抛出错误
} catch(e){
    if(e instanceof ReferenceError){
        // 处理ReferenceError 类型
    }
}

或

try {
    // 可能抛出错误
} catch(e){
    switch(e.constructor){
        case ReferenceError:
        // 处理ReferenceError异常
        break;
        case TypeError:
        // 处理TypeError异常
        break;
        case SyntaxError:        // 处理SyntaxError语法错误异常
        break;
        ...
    }
}

2. 捕获异步代码异常

try {
    let res = await fetch('/list');
    // 处理异步代码
} catch(e){
    // 处理异常代码
}

try {
    setTimeout( () => {
        console.log(b); // Uncaught ReferenceError: b is not defined
    },500)
} catch(e){
    console.log('执行', e)
}

try块报错了,catch没有捕获到,为什么会这样?

try catch 是同步捕获错误的,而定时器是异步的,在try 块执行的时候,其包裹的代码并没有报错,所以捕获不到。如果要捕获这个错误,定时器里的代码必须和try catch中的同时执行。

setTimeout(() => {
    try {
        console.log(b)
    }catch(e){
        console.log('执行', e)    
    }}, 500)

3.  try块的代码在外部执行,catch捕获不到。

try {
    function test(){
        console.log(b)
    }
} catch(e){
    console.log('执行', e)
} 
test()

4.  捕获异常并忽略

try {
    console.log(b)
} catch (e){
    // 忽略异常
}
注:生产环境不建议这么做, 开发环境调试代码时可以用来忽略一些报错

5.  finally 块中可以做一些资源的清理操作

try {
    
} catch(e){

} finally {
    // 根据实际项目业务需求可以做一些状态清空的操作
}

6. 重新抛出异常

try {
    console.log(d)
} catch(e){
    throw e // 异常抛出, 可以外面重新接收处理
}

如有需要完善或写的不对的地方,欢迎评论区交流。