zoukankan      html  css  js  c++  java
  • 用好js与nodejs中的try...catch

    对异常的捕获和处理是提高程序鲁棒性的一个重要方式,即使在javascript/nodejs等看似“很难写出bug”的弱类型语言里,异常捕获处理仍至关重要,这主要是因为:

    1.在一个代码块里,如果程序运行过程中自动、或主动(new Error/Exception)生成异常/错误后,若不主动去try...catch该异常,这个异常会逐层抛出,直至主程序,系统会按照框架默认方式处理该异常。

    2.在逐层抛出异常的过程中,每层代码块异常点之后的程序不会再被执行,除非进行try...catch异常处理。

    我们看几个简单的例子来验证一下。

    (() => {
      try{
        (()=>{
          nonExistentFunction();
          console.log('c');
        })();
        console.log( 'b' );
      }catch(e){
        console.log( e );
      }
    })();
    console.log( 'a' );
    

     打印结果:

    即,打印了最外层的catch内的异常处理信息和主程序接下来的部分,根据1,2可知,如果匿名函数最外层没有进行try...catch处理的话,a也不会被打印出来。

    这意味着,即使是“很难写出bug”的javascript也可能因为一个小小的异常导致整个程序歇菜!try...catch则是保证主干按流程执行完毕的关键实现。

    容易被误处理的异步异常

    在nodejs等异步IO密集场景,经常用异步回调函数来处理IO操作结果——不管是正确的数据还是异常Error,但此时的try...catch怎么来写?

    const fs = require('fs');
    try{
      fs.readFile( __dirname+'/15_fs1.js',(err,data) =>{
          if( err ){
            throw err;
          }else{
            console.log( data );
          }
      } );
    }catch(err){
      console.log( 'an error occured!',err );
    }
    
    console.log( 'hhh' );

    在文件不存在的情况下,按照try..catch的作用,我们认为应该在catch里捕捉到异常并执行异常处理语句,即打印“an error occured!XXX”;但实际结果呢?

    即,异常最后并未被目前缩写的catch所捕获,而是最终被系统级捕获并按照框架方式打印出了错误信息,这是为什么呢?主要是因为try...catch是代码块,是被同步解析的,当代码执行到try后,开始读文件操作,等待异步执行结果,但catch语句是紧接着try进行的,它并不会等待异步执行的结果,因此,当执行到catch的时候,回调里的throw error还没执行呢,当然catch不到了,主程序继续解析执行直到打印出'hhh'。随后当异步会调离throw err的时候没有catch可以捕获的到,只能层层抛出到最外层,由框架来捕获和执行。

    理解上述内容后,就该想到问题的关键点是try...catch的执行ticker与回调函数ticker不同步的问题,解决的办法也很简单,同步try...catch与callback函数的时钟—将try..catch放在callback里面。

    正确的代码示例:

    const fs = require('fs');
    
    fs.readFile( __dirname+'/15_fs1.js',(err,data) =>{
      try{
        if( err ){
          throw err;
        }else{
          console.log( data );
        }
      }catch(e){
        console.log( e );
      }
    } );
    console.log( 'hhh' );

    打印结果:

    19年要在使用新框架写好业务逻辑的基础上,提高自己输出代码的鲁棒性,经常去分析、反思可能出现异常的模块并进行forecast error的捕获处理,进一步提高自己的代码水平。

     ——学无止境,保持好奇。May stars guide your way.

    路漫漫其修远兮,吾将上下而求索。 May stars guide your way⭐⭐⭐
  • 相关阅读:
    架构与思维:设计容量,到底有多重要 ?
    MySQL全面瓦解25:构建高性能索引(案例分析篇)
    MySQL全面瓦解24:构建高性能索引(策略篇)
    MySQL全面瓦解23:MySQL索引实现和使用
    MySQL全面瓦解22:索引的介绍和原理分析
    C#9.0:Records
    C#9.0:Improved Pattern Matching
    C#9.0:Top-Level Programs
    C#9.0:Init
    MySQL全面瓦解21(番外):一次深夜优化亿级数据分页的奇妙经历
  • 原文地址:https://www.cnblogs.com/surfer/p/10291609.html
Copyright © 2011-2022 走看看