聊聊Javascript中try catch的2个作用

作者:zxg_神说要有光 时间:2024-04-22 13:25:57 

程序是从上到下顺序执行的,同时可以通过一些控制语句来改变执行的路线,受控制语句影响下,程序最终的执行路线就是控制流。

js 里面的控制语句有 if、for、while、try catch 等,它们都会改变程序的走向。

程序是操作数据的,随着程序的运行,也就是控制流的前进而改变的数据叫做数据流。

很明显,数据流是依赖控制流的,程序分析里面的数据流分析也是要先做控制流分析。

比如这样一段代码:


const a = 1;
let b;

if (a === 1) {
   b = '1111';
} else {
   b = '2222';
}

因为 a 为 1,所以会执行到 b = '1111';,这就是控制流,也就是程序最终执行的代码,可以用来分析程序的走向,做一些死代码删除之类的优化。

而随着控制流的执行,b 会被赋值为 2222,这就是数据流,也就是值的变化的过程,可以用来分析某个语句的变量的值。

程序是针对不同数据做不同的处理,如果数据有错误,那么处理程序也就没法处理了,就会报错,会中断后续的控制流。比如数据为空、数据格式不对等等。这时候就要通过 try catch 做错误处理,也叫异常处理。

我们做异常处理有两个目的:

1、对出错的逻辑做一些兜底处理。

比如参数解析有错误的时候,在 catch 里赋一个默认值。这种错误处理之后就没必要再报出来了。这种情况下 try catch 也是作为逻辑的一部分,相当于 if else。

2、对报的错做更场景化的描述。

JS 的报错是 JS 引擎抛出的,比如调用了一个 null 对象的方法会报 TypeError,使用了未声明的变量会报

ReferenceError。而具体的 Error 是在不同场景下报出的,就有不同的含义:

如果这个对象是来自用户输入的,那就是用户输入的有错误,如果这个对象是从服务端获取的,那就意味着服务端返回的数据有错误。在不同的场景下,同一个 Error 会有更具体的含义,所以我们要做 try catch。然后抛出一个自定义的错误,包含有场景信息的错误描述。

这点很多库和框架做的都比较好,报出的错都是有具体的场景信息,甚至还有解决方式,而且还有的通过错误编号做了管理,可以通过 errorno 来查询解决方式。这种就是对错误做了自定义的处理。

而很多业务代码中报的错就并没有做这种处理,是直接把原生 Error 给报出来了。我们会通过异常监控平台来收集一些 throw 到全局的错误,而这些错误往往都是比较原始的信息,虽然带上了错误位置和堆栈,但还要通过看源码来定位问题。

比如报了一个对象为空的错误,但是我怎么知道这是什么对象为空,会是什么原因,怎么解决,有没有编号。

如果我们能够对各种错误 catch 之后 throw 出一些具体场景的自定义错误,那是不是就好的多了。这点第三方库都做得很好,而业务代码很少有人注重场景化的自定义错误。

当然,前端业务代码的用户是通过界面来使用该软件的,其实只要对各种错误做一些 UI 上的提示就可以。而库的代码是给开发者用的,那么就要对各种错误做场景化的描述,甚至给错误编号并给出解决方案。

但我觉得业务代码也应该像第三方库代码那样来对待错误,不要把没有啥意义的原生错误报出来,而是报一些有具体含义的自定义错误,这样排查和解决问题就会简单很多。

不过虽然场景化的自定义错误可以更好的帮助排查问题,那也一定是建立在对该段代码可能报的错误有把握的情况下。要是自己报出的错误信息和实际的错误原因不一样,反而会增加排查问题的难度,还不如把原生错误报出来。

总结

程序执行的流程是控制流,受控制语句影响,执行的过程中会改变数据,数据的变化叫做数据流,控制流和数据流是程序分析里面经常分析的两个方面。

错误会中断控制流,我们要对错误做一些处理,通过 try catch。

错误处理有两个目的:

一个是做一些兜底的处理,相当于 if else,不需要再把错误报出来。

一个是做对原生的 JS 错误做场景化的描述,创建一个有更具体信息的错误对象抛出来。

这点很多库做的很好,甚至还会给错误编号并给出解决方式。但业务代码其实很多只做了给用户的 UI 上的反馈,没有对抛出的错误做场景化的包装。这就导致了错误监控平台收集到的错误都是比较原始的错误,需要查看源码来排查。如果也能像库的代码那样做一些场景化的错误包装,统计和排查起问题来会容易很多,这点大多数 Javascript 工程师都没做到。

来源:https://juejin.cn/post/7010023914612981774

标签:try,catch,js
0
投稿

猜你喜欢

  • Laravel框架数据库CURD操作、连贯操作总结

    2023-11-17 07:22:26
  • 数据库性能优化三:程序操作优化提升性能

    2024-01-14 08:58:49
  • pytorch常见的Tensor类型详解

    2022-10-25 19:34:01
  • SQL Server"错误 21002: [SQL-DMO]用户 * 已经存在问题解决

    2024-01-16 16:01:55
  • Linux环境下MySQL-python安装过程分享

    2024-01-15 12:50:41
  • python变量的存储原理详解

    2023-03-26 14:46:48
  • 如何在windows下安装Pycham2020软件(方法步骤详解)

    2023-05-19 14:07:30
  • Python Numpy 数组的初始化和基本操作

    2022-08-28 22:18:23
  • Python 条件,循环语句详解

    2023-10-17 11:17:41
  • MySql新手入门的基本操作汇总

    2024-01-23 15:10:19
  • Python在centos7.6上安装python3.9的详细教程(默认python版本为2.7.5)

    2022-05-09 18:58:43
  • 推荐技术人员一款Python开源库(造数据神器)

    2023-11-10 19:57:45
  • python中实现php的var_dump函数功能

    2023-11-16 07:11:04
  • 如何为Access数据库表添加日期或时间戳

    2008-11-21 12:46:00
  • SQL 中having 和where的区别分析

    2024-01-17 17:23:24
  • python实现图片中文字分割效果

    2023-03-11 16:39:42
  • Python wxPython库使用wx.ListBox创建列表框示例

    2021-12-06 21:10:56
  • Go map发生内存泄漏解决方法

    2024-05-05 09:29:52
  • golang beego框架路由ORM增删改查完整案例

    2024-05-09 15:00:59
  • Caffe图像数据转换成可运行leveldb lmdb文件

    2023-03-01 08:41:27
  • asp之家 网络编程 m.aspxhome.com