• 如何提高代码的健壮性


    健壮性(Robustness) 是指程序在遇到规范以外的输入,错误和异常时,仍能正常运行。简单来说,健壮代码的适应性很强,不会因为一些异常,就导致程序崩溃。

    不健壮的前端代码体现为:

    • 接口返回异常或报错时,页面白屏。

    • 用户做一些非常规操作时,页面白屏。

    一、如何写出健壮的前端代码

     

    要写出健壮的前端代码,就要处理规范以外的输入,错误和异常。具体来说,有4点:

    • 异常处理。

    • 输入检查。

    • 写法优化。

    • 第三方库的选择。

    下面,我们具体来说。

    (一)异常处理

    不做异常做处理,轻则导致功能出错,重则导致页面白屏。异常处理,可以分为如下几种情况。

    • 主动捕获运行时异常

    用try-catch捕获同步代码的运行时错误。如果是异步代码,需要转化成await的写法。如:

    try {  doSth()  await doSth2()} catch (e) {  // 处理异常}
    • 处理意料之外的全局运行时异常

    未被处理的JavaScript运行时错误(包括语法错误)发生时, window会触发error事件。这么处理:

    window.addEventListener(  'error',  (e) => {/* 处理异常 */})

    当一项资源(如<img>或<script>)加载失败时,加载资源的元素会触发error事件。这么处理:

    const img = new Image();img.addEventListener(  'error',  (e) => {/* 处理异常 */})img.src = 'xxx'
    • 异步代码:Promise reject的处理

    Promise被reject时,可以在then的第二个参数或catch中处理。如:

    p().then(onSuccess, onReject)p().catch(onReject)

    Promise reject没有被处理的话,window会触发unhandledrejection事件。可以统一来处理:

    window.addEventListener(  'unhandledrejection',  (e) => {/* 处理异常 */})
    • 用Axios时,接口报错的通用处理

    可以在Axios接口返回的拦截器中,加入接口报错的通用处理。例如:

    axios.interceptors.response.use(function (response) {  return response;}, err => {  // 报错处理  if(err.response) {    switch (err.response.status) {      case 400: err.message = '请求错误(400)'; break;      case 500: err.message = '服务器错误(500)'; break;      // ...    }  }  return Promise.reject(error);})
    • Vue的异常处理

    app.config.errorHandler = (err, vm, info) => {  // 处理异常}
    • React的异常处理

    React的生命周期函数ComponentDidCatch可以捕获子组件的异常。因此,可以在根组件外包裹一个组件来处理错误。如:

    class ErrorBoundary extends React.Component {  componentDidCatch(error, info) {    // 处理异常  }}

    使用:

    <ErrorBoundary>  <App /></ErrorBoundary>

    (二)输入检查

    当输入不满足条件时,要尽早返回或主动报错。这里的输入包括:接口的返回结果,函数的参数,组件的属性等。

    • 接口返回格式检查

    接口的返回会出现和前端预期不一致的情况。原因可能是:

    • 接口的返回结果变更,但未通知前端。

    • 一些特殊的请求参数,导致接口的返回和预期值不同。

    因此,我们要对接口返回格式做检查。我们来看个例子:

    const res = await fetchList()const list = res.map(...)

    如果接口返回的不是数组,程序就会报错。可以做类似这样的优化:

    const res = await fetchList()const list = Array.isArray(res) ? res.map(...) : []
    • 函数参数检查

    JavaScript是弱类型语言,函数的参数可以传任意值或不传参。因此,不对函数参数检查,会出现一些和预期不一致的情况。比如,期望实现两数求和的功能:

    function sum (a, b) {  return a + b}
    sum(3, 4) // 7。和预期一致sum() // NaN。和预期不一致sum('3', 4) // '34'。和预期不一致

    对函数参数做检查,可以这么优化:

    function sum (a, b) {  if(isNaN(parseFloat(a)) || isNaN(parseFloat(b))) {    throw 'param error. param should be a num'  }  return parseFloat(a) + parseFloat(b)}

    推荐使用TypeScript。可以用它检查函数参数。上面的代码用TypeScript这么写:

    function sum (a: number | string, b: number | string) {  return parseFloat(a as string) + parseFloat(b as string)}
    • 组件属性检查

    对组件的属性检查和函数参数检查类似,就不做赘述了。

    (三)写法优化

    很多写法优化能提升代码健壮性。这里介绍2点。

    • switch都需要有default来做异常或默认情况的处理。

    • 访问对象或数组前要做判断

    如:a.b.c改成a&&a.b&&a.b.c。如果用了TypeScript,可以这么写:a?.b?.c。

    (四)第三方库的选择

    使用第三库,可以减少造轮子,从而提升开发效率。但如果第三方包不健壮,用到第三方包的功能也就不健壮了。

    健壮的第三方库是成熟,稳定的。最好不要选择以下情况的第三方库:

    • 刚出来不久的。

    • 还没出稳定版的。如果库遵循的是语意化版本规范,主版本号为0的都不是稳定版。

    • 使用人数很少的。下载量少,star数低。

    • 没有代码测试的。

  • 相关阅读:
    桌面上嵌入窗口(桌面日历)原理探索(将该窗口的Owner设置成桌面的Shell 窗口,可使用SetWindowLong更改窗口的GWL_HWNDPARENT,还要使用SetWindowPos设置Z-Order)
    QQ截图时窗口自动识别的原理(WindowFromPoint, ChildWindowFromPoint, ChildWindowFromPointEx,RealChildWindowFromPoint)
    如何给开源的DUILib支持Accessibility(论述了DUILib的六个缺点,很精彩)
    从点击Button到弹出一个MessageBox, 背后发生了什么(每个UI线程都有一个ThreadInfo结构, 里面包含4个队列和一些标志位)
    Sessions, Window Stations and Desktops(GetDesktopWindow函数得到的桌面句柄, 是Csrss.exe创建的一个窗口)
    skip list
    理解对象模型图(Reading OMDS)
    Javascript与当前项目的思考
    Stub和Mock的理解
    https学习总结
  • 原文地址:https://www.cnblogs.com/fengyun2050/p/15753979.html
Copyright © 2020-2023  润新知