不要在代码中随便使用try...catch了

前言

 📫 大家好,我是南木元元,热爱技术和分享,欢迎大家交流,一起学习进步!

 🍅 个人主页:南木元元


目录

背景

js中的try...catch

try...catch运行机制

js的事件循环机制

try...catch无法捕获异步错误的原因

解决方法

结语


背景

之前面某物的时候,遇到了一个有关try...catch的问题,让我印象深刻,这里来记录分享一下。

面试官:下面代码有什么问题吗?

示例1:

try {
  setTimeout(() => {
    throw new Error('err');
  }, 200);
} catch (err) {
  console.log(err);
}

示例2:

try {
  Promise.resolve().then(() => {
    throw new Error('err');
  });
} catch (err) {
  console.log(err);
}

第一反应是,这不就是一个普通的try...catch捕获错误吗?但其实是有坑在里面的。

js中的try...catch

js中的try...catch是平时写代码时经常会使用的,它可以捕获代码中的异常并防止应用程序崩溃

try {
  // 可能会抛出异常的代码
} catch(error) {
  // 处理所有异常的代码
}

但try...catch并不能捕获所有的异常,这就需要了解try...catch的运行机制,这样才能保证我们合理地去使用它。

try...catch运行机制

当程序运行到try...catch里面时:

  • 如果未报错,则会忽略catch中的代码
  • 若报错,则不执行try报错内容后面的代码,转而执行catch中的代码

总结一下,能被try...catch捕捉到的异常,必须是在报错的时候,线程执行已经进入try...catch 代码块,且处在 try...catch 里面,这个时候才能被捕捉到。

js的事件循环机制

js是单线程语言,事件循环是js的执行机制。

  1. 所有同步任务都在主线程上执行,形成一个执行栈
  2. 在执行同步任务的时候,如果遇到了异步事件,会将该任务挂起,继续执行同步任务,当异步事件执行完后(如定时器到时,ajax请求返回),再将对应的回调加入到一个任务队列中等待执行,任务队列可以分为宏任务队列和微任务队列
  3. 当执行栈中的同步任务执行完毕后,会执行所有微任务,清空微任务队列
  4. 当执行完所有微任务后,再去执行宏任务队列中的下一个宏任务,不断循环,直到所有任务都完成。

这一套流程,就是事件循环。

错误原因

现在回到上述代码,其实就能够明白存在的问题是try...catch无法捕获异步错误

try...catch是同步执行的,而setTimeout和Promise.resolve()一个是宏任务,一个是微任务,都是异步任务,等到setTimeout和Promise.resolve()里面的事件进入到事件队列的时候,主线程已经离开了try...catch,所以try...catch无法捕获异步错误。

解决方法

只需在同步任务中使用try...catch即可,利用Promise和async/await的内在能力。

对于第一个示例:

new Promise((resolve, reject) => {
  setTimeout(() => {
    try {
      throw new Error('err');
    } catch (err) {
      reject(err);
    }
  }, 200); 
})
.then(() => {
  // 处理成功执行的情况
})
.catch((err) => {
  console.log(err); // 错误在这里被捕获
});

对于第二个示例:

// 方法一:使用Promise链式调用
Promise.resolve()
  .then(() => {
    throw new Error('err');
  })
  .catch((err) => {
    console.log(err); // 错误在这里被捕获
  });

// 方法二:使用async/await
async function handleError() {
  try {
    await Promise.resolve().then(() => {
      throw new Error('err');
    });
  } catch (err) {
    console.log(err); // 错误在这里被捕获
  }
}

handleError();

结语

因此,在代码中不要再随便写try...catch了,异步错误是无法被捕获的,而且像Promise有它自己的异常捕获方法,比try...catch更好用。

🔥如果此文对你有帮助的话,欢迎💗关注、👍点赞、⭐收藏、✍️评论,支持一下博主~ 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/448215.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

PMP没过能考下一次吗?PMP·考试不过下次费用多少?

每年都有许多人参加PMP考试,然而,并不是每个人都能一次性通过PMP考试,许多人可能会面临失败。带你了解PMP补考费用以及补考流程 01PMP补考费用是多少 考生若未能成功通过考试,还可以在一年PMI有效期内提交补考申请,若…

【文件增量备份系统】使用Mysql的流式查询优化数据清理性能(针对百万量级数据)

文章目录 功能介绍原始方案测试 流式处理测试 功能可用性测试 功能介绍 清理功能的作用是:扫描数据库中已经备份过的文件,查看数据源中是否还有相应的文件,如果没有,说明该文件被删除了,那相应的,也需要将…

多线程多进程

秋招面试的java八股文知识点补充以及iot 这里有一点阅读补充 线程和进程区别 什么是进程? 进程 (Process) 是计算机中的一个独立执行单元,是操作系统资源分配的基本单位。每个进程有各自独立的内存空间和资源,它们之间相互独立,相互之间…

长期异地就医备案有效期是多久?答记者问!

4、长期异地就医登记的有效期是多长? 答:异地长期就医登记长期有效。 如果您因个人原因需要变更长期居住地,只需提供相应的登记信息即可申请变更。 5、临时异地就医登记的有效期是多长时间? 答:临时异地就医登记包括…

ORACLE RAC数据库压力测试(swingbench)

------------------------------------------------------------------- 欢迎关注作者 墨天伦:潇湘秦的个人主页 - 墨天轮 CSDN:潇湘秦-CSDN博客 公众号:潇湘秦的DBA之路 ------------------------------------------------------------------- 为了验证跑在虚拟机上的or…

【C++庖丁解牛】模拟实现STL的string容器(最后附源码)

📙 作者简介 :RO-BERRY 📗 学习方向:致力于C、C、数据结构、TCP/IP、数据库等等一系列知识 📒 日后方向 : 偏向于CPP开发以及大数据方向,欢迎各位关注,谢谢各位的支持 目录 1.vs和g下string结构…

电机应用-步进电机进阶驱动

步进电机梯形加减速 什么是梯形加减速 假设该装置使用步进电机实现物体X的移动,系统要求从A点出发,到B点停止,移动的时间越短越好且系统稳定。 根据步进电机的特性,最大程度加大电机转速(提高脉冲频率)&a…

【脚本玩漆黑的魅影】全自动对战宫殿

文章目录 原理主要代码全部代码 原理 对战宫殿是让宠物自己打,不需要我们选技能,所以用来刷对战点数很合适。 需要准备三个主力。 主要是根据屏幕截图进行各种操作。 1,外面的对话,除了选自由级以外,其他都是直接点…

第十一个实验:数组和簇的混用,线性

实验内容: 输入5个元素的一维数组 显示每一个元素的值,索引和奇偶类型 第一步:新建项目 第二步:编程 创建一维数组,一共五个元素 ​​​ 选择数组索引部件 判断元素的奇偶性,把元素值,该元素索引和奇偶特性组成簇 复制4份,每一个元素一份

(day 2)JavaScript学习笔记(基础之变量、常量和注释)

概述 这是我的学习笔记,记录了JavaScript的学习过程,我是有一些Python基础的,因此在学习的过程中不自觉的把JavaScript的代码跟Python代码做对比,以便加深印象。我本人学习软件开发纯属个人兴趣,大学所学的专业也非软件…

MySQL技能树学习

MySQL三大范式: 第一范式主要是确保数据表中每个字段的值必须具有原子性,也就是说数据表中每个字段的值为不可再次拆分的最小数据单元。 第二范式是指在第一范式的基础上,确保数据表中除了主键之外的每个字段都必须依赖主键。 第三范式是在…

【设计模式】享元模式的使用场景及与其他共享技术的对比

文章目录 1.概述2.享元模式2.1.核心概念2.2.实现案例2.2.1.内部状态实现2.2.2.外部状态实现 2.3.更多场景 3.享元模式的一些对比3.1.与缓存的区别3.2.与池化技术的区别 4.总结 1.概述 享元模式(Flyweight Pattern)是一种非常常用的结构型设计模式&#…

实在TARS大模型斩获多项重磅大奖,AI领域实力认可

近日,实在智能TARS(塔斯)大模型凭借在多个垂直行业场景的优秀落地应用案例,以及AIGC领域的深耕和技术积累,荣获多项重磅大奖。 TARS大模型是是实在智能基于在自然语言处理(NLP)领域深厚的技术积…

MySQL常见的索引类型介绍

我将为您详细讲解 MySQL 中常见的索引类型,以及它们的使用场景、特点、区别和优势。索引是提高数据库查询性能的关键工具,它可以加速数据检索速度,减少服务器的负担。在 MySQL 中,索引类型主要包括 B-Tree 索引、哈希索引、全文索…

Linux进程概念僵尸进程孤儿进程

文章目录 一、什么是进程二、进程的状态三、Linux是如何做的?3.1 R状态3.2 S状态3.3 D状态3.4 T状态3.5 t状态3.6 X状态3.7 Z状态 四、僵尸进程4.1 僵尸进程危害 五、孤儿进程 一、什么是进程 对于进程理解来说,在Windows上是也可以观察到的&#xff0c…

Java线程的6种状态

线程在生命周期中并不是固定处于某一个状态而是随着代码的执行在不同状态之间切换。 NEW:初始状态,线程被创建出来但没有被调用start()RUNNABLE:运行状态,线程被调用了start()等待运行的状态BLOCKED:阻塞状态&#xf…

新手如何快速上手学习单片机?

读者朋友能容我,不使博文负真心 新开专栏,期待与诸君共享精彩 个人主页:17_Kevin-CSDN博客 专栏:《单片机》 学习单片机是一个有趣且有挑战性的过程。单片机是一种微控制器,广泛应用于各种电子设备和嵌入式系统中。在这…

开源向量数据库介绍

在开源矢量数据库的世界里,有些名字因其性能、灵活性和健壮性而脱颖而出。 1. Milvus Milvus 由 Zilliz 推出,是一款高度可定制的开源矢量数据库,在处理大规模数据方面大放异彩。由于其出色的可扩展性,当你需要处理大量数据时&a…

Python对头发二维建模(考虑风力、重力)

目录 一、背景 二、代码 一、背景 数值方法被用于创建电影、游戏或其他媒体中的计算机图形。例如,生成“逼真”的烟雾、水或爆炸等动画。本文内容是对头发的模拟,要求考虑重力、风力的影响。 假设: 1、人的头部是一个半径为10厘米的球体。…

python学习28

前言:相信看到这篇文章的小伙伴都或多或少有一些编程基础,懂得一些linux的基本命令了吧,本篇文章将带领大家服务器如何部署一个使用django框架开发的一个网站进行云服务器端的部署。 文章使用到的的工具 Python:一种编程语言&…