JavaScript 的try/catch/finally的使用场景

ry/catch/finally语句用于处理代码中可能出现的错误信息。
错误可能是语法错误,通常是程序员造成的编码错误或错别字。也 可能是拼写错误或语言中缺少的功能(可能由于浏览器差异)。
try:语句允许我们定义在执行时进行错误测试的代码块。
catch: 语句允许我们定义当 try 代码块发生错误时,所执行的代码块。
finally :语句在 try 和 catch 之后无论有无异常都会执行。
注意: catch 和 finally 语句都是可选的,但你在使用 try 语句时必须至少使用一个。
提示: 当错误发生时, JavaScript 会停止执行,并生成一个错误信息。使用 throw 语句 或 console.error() 来创建自定义消息(抛出异常)。如果你将 throw 和 try 、 catch一起使用,就可以控制程序输出的错误信息。

try或catch里有return时,先执行finally,再执行return;且finally中不能修改try和catch中变量的值

try {
  //运行(出错)
  throw '异常信息';
} catch (error) {
  //捕获
} finally {
  //最后一定执行。一般用于释放资源,如数据库连接、文件流等
}

**场景一:**try/catch/throw进行流程(if)控制,抛出自定义的异常信息。

function getStringToArray(str){
  try {
    if(str === undefined || str === null){
      //抛异常后,停止向下执行了,直接运行catch代码
      throw "出错了!这个不是字符串,undefined / null是没任何属性的";//throw语句:创建自定义错误, 抛出异常
    }
    if(Object.prototype.toString.call(str) === "[object Number]"){
      //抛异常后,停止向下执行了,直接运行catch代码
      throw "出错了!这个不是字符串,数字类型是没split方法属性的";
    }
    var arr = str.split(',');
    return arr;
  } catch (error) {
    console.error(error);//输出自定义的异常信息
    return [];
  }
}

getStringToArray(undefined);//输出:【出错了!这个不是字符串,undefined / null是没任何属性的】
getStringToArray(null);//输出:【出错了!这个不是字符串,undefined / null是没任何属性的】
getStringToArray(123);//输出:【出错了!这个不是字符串,数字类型是没split方法属性的】
getStringToArray("篮球,足球,排球");

场景二: 终止forEach的循环 。利用try/catch/throw禁用代码执行。注意:Promise.reject(‘错误信息’)只能阻止当前函数内往下执行。

var arr = [1,2,3,4,5];
try {
  arr.forEach(element => {
    if(element === 3){
      throw '循环终止了';
    }
    console.log('数字: ', element);
  });
} catch (error) {
  console.error(error);//输出异常信息:循环终止了
}

**场景三:**在vue项目中,首页大屏的组件地址是可配置的,为防止用户输入错误的组件地址,导致无法加载页面路由组件,进不了页面。需要用require预加载一次,try/catch捕获,异常就重新赋值可用的路由组件地址。

//后端返回的菜单数据
var menuData = [
  {
    "path": "/dashboard/analysis",
    "component": "dashboard/Analysis",
    "route": true,
    "meta": {
      "external": false,
      "keepAlive": false,
      "icon": "home",
      "permissionList": [
        {}
      ],
      "componentName": "Analysis",
      "title": "首页"
    },
    "name": "dashboard-analysis",
    "id": "1374671776843169794"
  }, 
  //{...},
  //{...},
  //{...},
];
menuData.forEach(element => {
  //预加载大屏组件地址,防止无效的组件地址,导致页面白屏,进不了系统
  if (element.path === "/dashboard/analysis") {
    try {
      require('@/views/' + element.component);//测试加载大屏组件
    } catch (error) {
      console.error(`配置了无效的大屏组件地址【${element.component}】:`, error);
      element.component = 'dashboard/*******';//重新设置有效的大屏组件
    }
  }
});

//vue组件,组件地址输入框校验的部分代码如下
export default {
  data() {
    return {
      rules: {
        component: [
          {
            required: true,
            message: '请输入组件地址',
            trigger: 'change'
          },
          {
            validator(rule, value, callback) {
              if (value) {
                try {
                  require('@/views/' + value);//测试加载大屏组件
                  return callback();
                } catch (error) {
                  //代码内不存在该组件
                  return callback(new Error('组件地址不正确'));
                }
              } else {
                return callback(new Error('组件地址不能为空'));
              }
            }, trigger: 'blur'
          },
        ]
      }
    }
  },
  methods: {}
}

**场景四:**输入框,用户输入字母表达式,要想知道表达是否正确,可以用try/catch/eval对表达式进行处理

var express = 'a + b + (c * e)';//用户在输入框,输入的表达式
var arr = "abcdefghijklmnopqrstuvwxyz".split("");
arr.forEach((element,index) => {
  express = express.replaceAll(element,index + 1);//将字母替换成数字,
});

try {
  eval(express);//将字符串(数字)运算,合法则通过
} catch (error) {
  //不通过校验
  new Error(`计算公式异常,转换后无法计算`);
}

**场景五:**输入框输入json数据字符串(请求头header),try/cath捕获异常进行校验。

var str = "{a:111,b:}";
try {
  JSON.parse(str);//
} catch (error) {
  console.log(new Error(`json数据不正确`));
}

**场景六:**数据不可控,容易出错,需要加try/cath捕获异常。

try {
  var data = [];//后端返回比较复杂且不确定
  for (let i = 0; i < data.length; i++) {
    const element = data[i];
    //数据处理、转换,可能会出错
  }
} catch (error) {
  alert('数据处理出错了!');
}

捕获不了的异常。注:外层的try/catch无法捕获异步队列微任务、宏任务内的异常,要想捕获宏任务内的异常,try/catch代码只能写在微任务、宏任务代码内。 如果try块作用域内执行setTimeout方法,从setTimeout定时器里面把错误err信息throw扔出来,catch外部是不能捕获的,因为setTimeout是在临时寄存器上执行的,所以不在一个栈上处理上下文的,错误err无法被捕获。

try {
  (async function(){
    //加了async后try捕获不到函数内的异常了。去掉async后catch就捕获异常了
    var num = undefined;
    num.toString();//错误代码,由浏览器抛出异常
  })();
} catch (error) {
  console.error('异常输出:',error);//没捕获到异常
}
function getData() {
  return new Promise((resolve, reject) => {
    var xhr = new XMLHttpRequest();
    xhr.open('GET', 'https://cdn.bootcss.com/vue/2.6.14/vue.min.js', false);
    xhr.onreadystatechange = function () {
      //异步代码,不能捕获异常(宏任务)
      // readyState == 4说明请求已完成
      if (xhr.readyState == 4) {
        if (xhr.status == 200 || xhr.status == 304) {
          resolve();
          var str = undefined;
          str.split(',');//错误代码,由浏览器抛出异常
        }
      }
    }
    xhr.send();
  });
}
(async function () {
  try {
    setTimeout(() => {
      //定时器内的异常不被捕获(宏任务)
      var str = undefined;
      str.join(',');//错误代码,由浏览器抛出异常
    }, 100);

    Promise.resolve().then(() => {
      //then(微任务)
      var arr = null
      arr.push(111);//错误代码,由浏览器抛出异常
    });

    await getData().then(() => {
      //await then函数内,能捕获异常,同一栈上处理上下文,能捕获异常
      var num = undefined;
      num.toString();
    });
  } catch (error) {
    console.error('异常输出:', error);//没输出
  }
})();
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
try/catch语句是JavaScript处理异常的一种标准方式。它的基本语法是在try代码块编写可能导致错误的代码,如果出现异常,程序会跳转到catch代码块进行异常处理。 在try/catch语句catch代码块是可选择的,用于捕获并处理异常。如果try代码块发生异常,程序会跳转到catch代码块执行相应的异常处理逻辑。而finally代码块是一定会执行的,无论try代码块是否发生异常,finally代码块都会被执行。 异常抛出后会一直返回调用函数(或者说上一层函数),直到被catch到。因此,可以将catch语句写在一起,以便对多个异常进行统一处理,从而使代码更加整洁和方便。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [try-catch语句](https://blog.csdn.net/weixin_42561383/article/details/99687113)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [trycatch语句解析](https://blog.csdn.net/weixin_46953330/article/details/129556570)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [try/catch/throw](https://download.csdn.net/download/weixin_38595473/14887209)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值