博客
关于我
try……catch的异常捕获机制
阅读量:755 次
发布时间:2019-03-23

本文共 1724 字,大约阅读时间需要 5 分钟。

try catch 枌造的陷阱与丧亡

在 JavaScript 开发过程中,try-catch 构造是一个非常实用的工具,用于异常处理和流量控制。但是,它的使用并非毫无缺陷,也有不容忽视的坑点和瑕疵。既然好几篇参考文章已经提到过 try-catch 的基础知识,那我就从一些容易被低估的点入手,剖析这个构造的优缺点。

try 的目的不是保护代码,而是能否捕捉到异常?

很多开发者有这样的误解:只要把代码放到 try 里面,就可以捕捉到任何类型的异常。但这种想法有点儿危险。事实上,try catch 构造的本质目的是尽可能地保护后面代码的执行。当程序运行到试块(trial block,即try部分)的时候,如果没有发生错误,后面的catch block就不会执行。如果发生错误,catch block则会被执行。

要想真正捕捉到一个异常,必须满足两个条件:

  • 异常必须是从当前线程执行中抛出来的。
  • 这个异常必须发生在 try-catch 构造包围的代码块范围内。
  • 这样的限制意味着,当错误在语法检查阶段就被发现时(如语法错误),就会structions因为后续的代码从未执行过,自然无法被捕获。

    try-catch 不是万能钩

    虽然 try-catch 能够捕捉到大部分异常,但它并不是对所有问题都能够有效应对。最常见的是:

    1. 语法错误无法被捕捉

    语法错误的检查是发生在语法解析阶段的,在代码执行之前。如果代码本身没问题,才会被一个在线安然运行。例如,在一个函数内部有一个语法错误,这将在解析阶段就被发现,抛出一个 SyntaxError。由于此时程序还没进入 try-catch 块,后续的代码就无法捕捉到这样的异常。

    2.catch 异步操作的异常无法被捕获

    这种说法有些绝对,特别是在处理 promise 或 async/await 的情况下,try-catch 可以构成某些错误。比如在一个正常的情况下,除非使用 await,否则由 promise 初始化的错误将不会被 try-catch 捕获。

    举个例子:

    try {  setTimeout(() => {    console.log(a.b);  }, 100);} catch (e) {  console.log('捕获到异常', e);}console.log(111);

    输出的结果是 111,而不是捕获到 a 未定义的错误。这是因为 setTimeout 是一个异步操作,主线程离开了 try-catch 块才执行它。

    要捕捉到这样的错误,我们需要使用 async/await,并将 promise 导出给 try-catch:

    function fetchPromise() {  return new Promise((resolve, reject) => {    setTimeout(() => {      resolve('成功');    }, 100);  });}try {  const result = await fetchPromise();  console.log('结果:', result);} catch (e) {  console.log('捕获到异常:', e);}

    3. try-catch 无法捕捉 Promise 错误

    大多数情况下,除了使用 await,try-catch 无法捕捉 Promise 错误,因为这些错误是由 Promise 的 reject 方法触发的,且这些错误由 Promise 对象本身处理,以避免处置多线程的问题。

    try-catch 的合理使用

    • 不要试图用 try-catch 来处理所有可能的错误,但在异步操作中使用可以捕获部分错误。
    • 在处理复杂的网络请求或数据库操作时,考虑用 try-catch 来优化异常处理流程。
    • 由于 HTML 解析是同步的,所以在构建 DOM 的过程中,try-catch 或许会捕获一些错误。

    总的来说,try-catch 构造是一个强大的工具,但要用对它,它并不是万能钩。通过理解它的工作原理,如何以及在什么情况下使用,可以更高效地开发出更健壮的代码。

    转载地址:http://gfczk.baihongyu.com/

    你可能感兴趣的文章
    MySQL - ERROR 1406
    查看>>
    mysql - 视图
    查看>>
    MySQL - 解读MySQL事务与锁机制
    查看>>
    MTTR、MTBF、MTTF的大白话理解
    查看>>
    mt_rand
    查看>>
    mysql /*! 50100 ... */ 条件编译
    查看>>
    mudbox卸载/完美解决安装失败/如何彻底卸载清除干净mudbox各种残留注册表和文件的方法...
    查看>>
    mysql 1264_关于mysql 出现 1264 Out of range value for column 错误的解决办法
    查看>>
    mysql 1593_Linux高可用(HA)之MySQL主从复制中出现1593错误码的低级错误
    查看>>
    mysql 5.6 修改端口_mysql5.6.24怎么修改端口号
    查看>>
    MySQL 8.0 恢复孤立文件每表ibd文件
    查看>>
    MySQL 8.0开始Group by不再排序
    查看>>
    mysql ansi nulls_SET ANSI_NULLS ON SET QUOTED_IDENTIFIER ON 什么意思
    查看>>
    multi swiper bug solution
    查看>>
    MySQL Binlog 日志监听与 Spring 集成实战
    查看>>
    MySQL binlog三种模式
    查看>>
    multi-angle cosine and sines
    查看>>
    Mysql Can't connect to MySQL server
    查看>>
    mysql case when 乱码_Mysql CASE WHEN 用法
    查看>>
    Multicast1
    查看>>