如何给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)通过 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;
       }
     }
   }
 }

向上查找 async 函数

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

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

这里要注意,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()
  }
}

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

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()));
       }
     }
   }
 }

添加用户选项

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

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

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

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

babel插件的安装使用

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

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

babel插件的安装使用

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

其他参考资料

Babel 插件手册

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

原文地址:

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

A Lucky Boy

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值