• js中错误处理机制


    1.基本知识

    1. 错误对象

    Error,SyntaxError,RangeError, ReferenceError,TypeError,URIError

    上面的都是构造函数;

    new 命令可以生成错误实例对象;可以传入描述作为参数,成为实例对象的message属性;

    除了message属性,还有两个非标准属性(name, stack)stack是调用栈

    var err = new Error("错误实例");
    err.message; // "错误实例"
    err.name; //"Error"
    err.stack;//"Error: 错误实例 at <anonymous>:1:11"

    2. throw语句

    throw语句,如果不进行捕获(try...catch...),会中断当前script脚本中throw之后的所有代码执行。

    <script>
        function test(){
            console.log('1');
            setTimeout(() => console.log('2')); //异步任务,下一轮执行,相当于最后执行
            throw new Error("err"); //未捕获,这个script内的后面的代码都不执行
            setTimeout(() => console.log('3')); // throw后
            console.log('4'); // throw后
        };
        function a() { console.log('5') }
        test();
        a(); //throw后
    </script>
    <script>
        function b() { console.log('6') }
        b(); // 另一个脚本
    </script>
    // 运行结果如下:
    1
    Error: err
    6
    2

    如果在定时器中抛出异常,不会中断定时器之外的代码执行。定时器回调函数相当于自己一个“进程”。

    示例: 将上面的未捕获异常放在setTimeout中

    <script>
        function test(){
            console.log('1');
            setTimeout(() => console.log('2'));
            setTimeout(() => {throw new Error("err")}); //改为异步后,只影响本身
            setTimeout(() => console.log('3'));
            console.log('4');
        };
        function a() { console.log('5') }
        test();
        a();
    </script>
    <script>
        function b() { console.log('6') }
        b();
    </script>
    //运行结果如下
    1
    4
    5
    6
    2
    Uncaught Error: err
    3

    throw命令可以抛出任何类型的值;抛出什么,则捕获的就是什么!

    try{ 
        throw "error"
    } catch(err){
        console.log(err); //"error"
    }

    3.try...catch...finally..语句

    使用try...catch...语句后,可以捕获错误,防止代码崩溃;

    1)js中,程序执行遇到return, throw后,后面的语句不再执行;

    try{
        throw "this is a error";
        console.log("after throw"); // 永远不会执行
    } catch(error) {
        console.log(error); 
    }
    // 运行结果
    "this is a error"

    2)浏览器中单独的try代码块中不能使用return;否则报错;而且catch无法捕获

    try{
        return "this is a error";
    } catch { 
    }
    // Uncaught SyntaxError: return not in a function

    由上面可以知道,return语句必须用在function中。另外,yield语句也是必须在Generator函数中被调用。

    如果想在try/catch/finally代码块中使用return语句,可以在外面包裹一层function。

    3)catch语句

    如果try代码块中代码本身不抛出异常,也没有手动抛出异常,程序永远不会进入catch代码块。

    try {
       console.log("throw nothind");
    } catch { // 参数可以省略
       console.log("永远不会执行"); // try没有抛出错误,不会进入catch;永远不会被打印,
    }

    如果try代码块中抛出异常,则代码进入catch代码块执行完后,继续原来的代码执行。

    try {
        throw "error";
     } catch { // 参数可以省略
        console.log("catch")
     }
     console.log('after');
     // 运行结果如下:
    catch
    after

    4)finally语句

    finally语句不论是否抛出异常,都会执行。且try后者catch中的return语句取值会在finally之前取值。

    var count = 1;
    function test() {
        try {
            console.log("try");
            throw new Error("this is a error");
        } catch(err) {
            console.log("catch error");
            return count;
        } finally {
            console.log("finally")
            count+=1;
        }    
        console.log("after"); //永远不会执行
    }
    console.log(test()); 
    // 运行结果如下
    try catch error finally 1 //最后返回1,说明return在finally执行前先执行,但是最后才返回

    如果在该代码块有return语句,会覆盖try,catch中的return语句

    var count = 1;
    function test() {
        try {
            console.log("try");
            throw new Error("this is a error");
        } catch(err) {
            console.log("catch error");
            return count;
        } finally {
            console.log("finally")
            count+=1;
            return count;
        }    
        console.log("after"); //永远不会执行,因为前面有return语句
    }
    console.log(test()); 
    //  运行结果如下
    try
    catch error
    finally
    2 //执行的是finally语句中的return语句

    如果在该代码块中有return语句,会覆盖catch中的throw语句;

    var count = 1;
    function test() {
        try {
            throw new Error("this is a error");
        } catch(err) {
            console.log("catch error");
            throw err; // 不会执行;正常catch中遇到throw/return进入finally,等执行完finally代码块,返回这里抛出异常
        } finally {
            return count; // return 后不会返回catch代码块;如果没有return,会返回catch模块继续抛出异常,然后被外部的try...catch捕获
        }    
    }
    try {
        test(); 
    } catch(err) {
        console.log("catch test error"); // 不会执行
    }
    // 运行结果如下:
    catch error
    1 //返回1

    4. finally语句应用

    示例: 操作文件时,打开文件写入,不管是否写入成功,都要关闭文件

    // 伪代码如下
    openFile();
    try {
        writeFile()
    } catch(err) {
        console.log("写入失败");
    } finally {
        closeFile(); // 总要执行
    }

    2. 实践应用

    当使用接口请求服务器数据时,一般都要使用try...catch...方法,预防接口报错,程序崩溃!

  • 相关阅读:
    ABP源码分析四十:ZERO的Application和Tenant
    ABP源码分析三十九:ABP.Hangfire
    ABP源码分析三十八: ABP.Web.Api.OData
    ABP源码分析三十七:ABP.Web.Api Script Proxy API
    232. 用栈实现队列
    155. 最小栈
    725. 分隔链表
    328. 奇偶链表
    148. 排序链表
    143. 重排链表
  • 原文地址:https://www.cnblogs.com/lyraLee/p/11651433.html
Copyright © 2020-2023  润新知