libreportparam2.dll无法继续执行代码_你代码的异常真的能被try catch到吗?

前言

在平时开发过程中,通常遇到异常,浏览器会停止执行JS并抛出异常,但有时候我们并不想一些异常中断代码执行,就会用到try...catch...代码块来捕获JS异常,也方便我们定位错误调试代码,帮助我们及时解决bug,但你有没有想过,是不是在try代码块中写我们的代码,就能被catch抛出异常呢?

我们知道,一般在try代码块中,执行的代码若有异常,则可能被catch抛出异常,我说的是可能,那么,你能否用一句话来描述try...catch...能否正确捕获到JS异常?

在这里,先抛砖引玉吧:try catch能捕获到的异常,必须是JS代码在执行阶段时抛出的并且是处在try catch代码块中。

那么,我们下面来分析下try catch到底是怎么捕获异常的。主要分为三个阶段,即try catch 前、中、后(好像有点废话)

try catch之前

若在代码报错时,JS线程执行未进入try catch,则无法捕获异常。比如语法异常 syntaxError,因为语法异常是在语法检查阶段就报错了,JS代码还没开始执行,即没有在try catch代码块中执行,因此也就无法捕获到异常。如以下代码:

try {  var a = null;  a.} catch (e) {  console.log(‘error’, e);}// Uncaught SyntaxError: Unexpected token '}'

try catch之中

代码执行阶段报错时,此时处于try 代码块之中,则能正确捕获到异常。如下代码,执行fn()方法时,JS执行的线程已经进入try代码块中,所以异常能被捕获到。

```jstry {  function fn() {    a.b  }  fn();} catch(e) {  console.log(‘error’, e);}// error ReferenceError: a is not defined```

try catch之后

这里很显然代码执行报错时,JS执行完try catch了,此时是无法捕获到异常的。当然,我们说的try catch之后执行,除了在其之后调用之外,还有一种情况就是在try代码块中执行异步代码,了解JS事件队列,我们知道,try catch在主线程已经执行完毕了,才会去执行异步队列的代码,这个时候异步代码抛出的异常是无法被try catch捕获到错误的。如下代码:

try {    setTimeout(()=>{        console.log(a.b);      }, 100)} catch (e){    console.log('error',e);}console.log(123);// 123// Uncaught ReferenceError: a is not defined

Promise的异常捕获

我们知道Promise可以异步执行代码,但是在实例化Promise时,Promise传的参数是一个马上执行的函数,真正异步执行是其内部的状态转化机制,来等待执行的结果状态,通过then或catch来获取返回的结果。那么在Promise内部执行的代码抛出的异常能不能被try catch捕获呢?直接上代码运行看看:

try {  new Promise((resolve, reject) => {    a.b;  }).then((res)=> {    console.log(res);  }, (e) => {​    console.log(‘promise error’, e);  })} catch(e) {  console.log(‘try catch error’, e);}// promise error ReferenceError: a is not defined

从以上代码运行结果可以看出,异常是被Promise自身捕获的,其实,Promise的异常是由reject方法或者Promise.prototype.catch来捕获的,并且不会往上抛出异常,故外层的try catch无法捕获到Promise抛出的异常。这里我们可以得出,就是尽量不要给Promise套上try catch,因为异常无法被往上抛出,用Promise自身提供的方法去捕获即可。

但是,是不是try catch就木有办法捕获Promise抛出的异常了吗?答案那当然是阔以捕获啦~我们看下面这段代码:

function a() {  return new Promise((resolve, reject) => {    setTimeout(() => {      reject(1);    })  })}try {  await a();} catch(e) {  console.log('error', e);}console.log(111);// error 1// 111

神奇的事情发生了,try catch能捕获到异常,其实这就归功于await,我们知道await后可执行一个异步代码,并且需要等到异步代码执行返回结果才会继续执行,所以执行a异步方法,等待结果返回后,此时JS代码执行还是停留在try catch代码块中,Promise通过reject方法抛出的异常就被捕获了。所以,一般在执行异步任务时,要在try catch中捕获异常,还是配合async/await用。

a98d111c1c1c6844a7f42aadd21a4e9a.png

感谢您阅读我分享创作的文章,文章会同步在本人公众号【前端精神小伙】中,可关注阅读往期文章。

欢迎一起学习和交流,debug佳也将持续为大家分享更多前端技术干货。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值