• 如何给async await批量添加try…catch?


    async和await是什么?

    ​ 在前端开发的工作过程中,async和await想必大家都很熟悉,只要发请求或者是基于promise的异步操作,都可以用promise的终极解决方案来操作,这样写可以使代码变得简介,并且在看代码的时候可以按照同步的代码去书写,(仅仅看上去是同步的,本质还是异步的

    try…catch是什么东西?那么为什么要用try…catch呢?它的存在是为了解决什么问题的?

    带着上边的三个问题我们来一一解答,try…catch是什么呢?举个例子,在生活中我们难免会犯错,当我们知道有些错误不可避免或者可能会出错的时候,我们会先去想好如果犯了错,应该怎么解决这个错误,那么try…catch也是如此,它是为了解决我们在书写代码的过程中可能会出错的地方,用try…catch包裹起来,如果这段代码成功的话,它是不会去执行catch里的代码的,相反,如果失败,它是不会去执行try里的代码的,当然我们有时候会不管这段代码成功或者失败,都要执行一些相应的操作,那么,就可以将代码写到finally里面,这样的话,无论这段代码成功或者失败,都会去执行这段代码,类似于promise当中的.then、.catch和.finally,而我们利用async和await去发送请求时就可以利用try和catch去包裹一下,以防出错时候用户不知道是什么问题

    如何给async await批量添加try…catch

    ​ 如果我们每次写一个请求,手动给请求添加一个try…catch,这样肯定是可以的,总所周知,程序员都是比较懒的,能少写一个单词绝不多写一个字母,那么如何给async和await批量添加try…catch呢?

    ​ 带着这个问题,我打开了百度,打算面向百度编程,最后是在掘金上边找到了一个利用babel来解决的方案,在此做一个记录,希望可以帮到更多的人~~~~

    babel插件的实现思路

    1)借助AST抽象语法树,遍历查找代码中的await关键字

    2)找到await节点后,从父路径中查找声明的async函数,获取该函数的body(函数中包含的代码)

    3)创建try/catch语句,将原来async的body放入其中

    4)最后将async的body替换成创建的try/catch语句

    插件的基本格式示例

    module.exports = function (babel) {
       let t = babel.type
       return { 
         visitor: {
           // 设置需要范围的节点类型
           CallExression: (path, state) => { 
             do soming ……
           }
         }
       }
     }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    1)通过 babel 拿到 types 对象,操作 AST 节点,比如创建、校验、转变等

    2)visitor:定义了一个访问者,可以设置需要访问的节点类型,当访问到目标节点后,做相应的处理来实现插件的功能

    寻找await节点

    回到业务需求,现在需要找到await节点,可以通过AwaitExpression表达式获取

    module.exports = function (babel) {
       let t = babel.type
       return { 
         visitor: {
           // 设置AwaitExpression
           AwaitExpression(path) {
             // 获取当前的await节点
             let node = path.node;
           }
         }
       }
     }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    向上查找 async 函数

    通过findParent方法,在父节点中搜寻 async 节点

    // async节点的属性为true
    const asyncPath = path.findParent(p => p.node.async)
    
    • 1
    • 2

    这里要注意,async 函数分为4种情况:函数声明 、箭头函数 、函数表达式 、函数为对象的方法

    // 1:函数声明
    async function fn() {
      await f()
    }
    
    // 2:函数表达式
    const fn = async function () {
      await f()
    };
    
    // 3:箭头函数
    const fn = async () => {
      await f()
    };
    
    // 4:async函数定义在对象中
    const obj = {
      async fn() {
          await f()
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    需要对这几种情况进行分别判断

    module.exports = function (babel) {
       let t = babel.type
       return { 
         visitor: {
           // 设置AwaitExpression
           AwaitExpression(path) {
             // 获取当前的await节点
             let node = path.node;
             // 查找async函数的节点
             const asyncPath = path.findParent((p) => p.node.async && (p.isFunctionDeclaration() || p.isArrowFunctionExpression() || p.isFunctionExpression() || p.isObjectMethod()));
           }
         }
       }
     }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    添加用户选项

    用户引入插件时,可以设置excludeincludecustomLog选项

    exclude: 设置需要排除的文件,不对该文件进行处理

    include: 设置需要处理的文件,只对该文件进行处理

    customLog: 用户自定义的打印信息

    babel插件的安装使用

    npm网站搜索babel-plugin-await-add-trycatch
    在这里插入图片描述

    有兴趣的朋友可以下载玩一玩

    babel插件的安装使用

    最终的代码可以参考这位大佬的github仓库

    其他参考资料

    Babel 插件手册

    嘿,不要给 async 函数写那么多 try/catch 了

    原文地址:

    阿里面试官:如何给所有的async函数添加try/catch?

  • 相关阅读:
    负责任de老师
    Spring Cloud(二):Spring Cloud Alibaba Nacos
    TypeScript 中 type 和 interface 有什么区别?
    MySQL进阶(数据库引擎)——MyISAM和InnoDB引擎的区别
    这个面试官真烦,问完合并又问拆分。
    力扣题目训练(18)
    贝叶斯核机回归-因果中介分析 (BKMR-CMA)causalbkmr R包
    (附源码)ssm旅游公司网站 毕业设计 201105
    Python的比较运算符查询表
    海外IP代理如何助力跨境电商?
  • 原文地址:https://blog.csdn.net/weixin_43797577/article/details/127973367