JS学习笔记——关于try finally异常机制的基础介绍和使用

前提

通常我们在代码中捕获错误异常,使用的是try{ }catch{ }机制,今天在看项目时,突然发现里面使用try{ }finally{ }捕获异常,这种方法之前使用的还不是很多,所以也查了资料,深入研究研究。

try finally

(1)语法

异常机制中还有一个重要的部分,就是finally。
catch后面可以跟finally语句,语法如下所示:

try{
    //可能抛出异常
}catch(Exception e){
    //捕获异常
}finally{
    //不管有无异常都执行
}

finally内的代码不管有无异常发生,都会执行。

(2)运行机制
  • 如果没有异常发生,在try内的代码执行结束,就执行finally内代码
  • 如果有异常发生且被catch捕获,在catch内的代码执行结束后,就执行finally内代码
  • 如果有异常发生但没被捕获,则在异常被抛给上层之前执行

值得注意的是,try/catch/finally语法中,catch不是必需的,也就是可以只有try/finally表示不捕获异常异常自动向上传递,但finally中的代码在异常发生后也执行

(3)return
(1)try中有return

在try / catch / finally 语句里面,有一个细节,就是如果在try或者catch内有return,则这时return语句会在finally语句执行结束后才会执行,但是finally并不能立即改变返回值,我们可以看下面代码:

import React , { useState , useEffect} from 'react';
const App = () => {
    const [val , setVal] = useState(0)
    const getResult = () => {
        try {
            return setVal(1234)
        } catch (error) {
            console.log('error',error)
        }finally{
            setVal(9999)
        }
    }
    useEffect(() => {
        getResult()
    }, [])
    return (
        <div>
            <h1>
                哈哈啊哈哈哈
            </h1>
            <h2>
                当前的val值:{val}
            </h2>
        </div>
    );
};

export default App;

效果图:
在这里插入图片描述
可以看出:
这个函数的返回值是9999,而不是1234。实际执行过程是:

  1. 在执行到try内的return setVal(1234)语句前时,会先将返回值val保存在一个临时变量
  2. 然后才执行finally语句
  3. 最后try再返回那个临时变量finally中对val的修改不会被返回
(2)finally中有return

如果在finally中也有return语句呢,这时会是什么情景呢?
如果finally里面也含有return,那么try和catch内的return会丢失,实际会返回finally中的返回值

事实上,finally中有return不仅会覆盖try和catch内的返回值,还会掩盖try和catch内的异常,就像异常没有发生一样,比如说:

import React , { useState , useEffect} from 'react';
const App = () => {
    const [val , setVal] = useState(0)
    const getResult = () => {
        try {
            let aaa = 111/0
            return setVal(aaa)
        } catch (error) {
            console.log('error',error)
        }finally{
            setVal(9999)
        }
    }
    useEffect(() => {
        getResult()
    }, [])
    return (
        <div>
            <h1>
                哈哈啊哈哈哈
            </h1>
            <h2>
                当前的val值:{val}
            </h2>
        </div>
    );
};
export default App;

效果图:
在这里插入图片描述
可以发现:

  • try里面的函数有错误,但是并没有异常抛出。
  • finally里面的return把错误给覆盖掉了,而且不再向上传递。

其实,finally中不仅return语句会掩盖异常,如果finally中抛出了异常,则原异常就会被掩盖,看下面代码:

import React , { useState , useEffect} from 'react';
const App = () => {
    const [val , setVal] = useState(0)
    const getResult = () => {
        try {
            let aaa = 111/0
            return setVal(aaa)
        } catch (error) {
            console.log('error',error)
        }finally{
            let bbb = 33/0
            // throw new Error('出错了')
            return (
                setVal(bbb),
                console.log('finally error')
            )
        }
    }
    useEffect(() => {
        getResult()
    }, [])
    return (
        <div>
            <h1>
                哈哈啊哈哈哈
            </h1>
            <h2>
                当前的val值:{val}
            </h2>
        </div>
    );
};
export default App;

效果图:
在这里插入图片描述
可以发现:

  • finally里面抛出了错误

所以,一般而言,为避免混淆,应该避免在finally中使用return语句或者抛出异常,如果调用的其他代码可能抛出异常,则应该捕获异常并进行处理。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值