async/await优雅的错误处理方法总结


Posted in Javascript onJanuary 30, 2019

前言

node.js的世界,从callback开始,不会止于async.

本文将给大家详细介绍关于async/await优雅的错误处理的相关内容,下面话不多说了,来一起看看详细的介绍吧

async/await优雅的错误处理

一般情况下 async/await 在错误处理方面,主要使用 try/catch,像这样

const fetchData = () => {
 return new Promise((resolve, reject) => {
  setTimeout(() => {
   resolve('fetch data is me')
  }, 1000)
 })
}

(async () => {
 try {
  const data = await fetchData()
  console.log('data is ->', data)
 } catch(err) {
  console.log('err is ->', err)
 }
})()

这么看,感觉倒是没什么问题,如果是这样呢?有多个异步操作,需要对每个异步返回的 error 错误状态进行不同的处理,以下是示例代码

const fetchDataA = () => {
 return new Promise((resolve, reject) => {
  setTimeout(() => {
   resolve('fetch data is A')
  }, 1000)
 })
}

const fetchDataB = () => {
 return new Promise((resolve, reject) => {
  setTimeout(() => {
   resolve('fetch data is B')
  }, 1000)
 })
}

const fetchDataC = () => {
 return new Promise((resolve, reject) => {
  setTimeout(() => {
   resolve('fetch data is C')
  }, 1000)
 })
}

(async () => {
 try {
  const dataA = await fetchDataA()
  console.log('dataA is ->', dataA)
 } catch(err) {
  console.log('err is ->', err)
 }

 try {
  const dataB = await fetchDataB()
  console.log('dataB is ->', dataB)
 } catch(err) {
  console.log('err is ->', err)
 }

 try {
  const dataC = await fetchDataC()
  console.log('dataC is ->', dataC)
 } catch(err) {
  console.log('err is ->', err)
 }
})()

这样写代码里充斥着 try/catch,有代码洁癖的你能忍受的了吗?这时可能会想到只用一个 try/catch。

// ... 这里 fetch 函数省略

(async () => {
 try {
  const dataA = await fetchDataA()
  console.log('dataA is ->', dataA)
  const dataB = await fetchDataB()
  console.log('dataB is ->', dataB)
  const dataC = await fetchDataC()
  console.log('dataC is ->', dataC)
 } catch(err) {
  console.log('err is ->', err)
  // 难道要定义 err 类型,然后判断吗??
  /**
   * if (err.type === 'dataA') {
   * console.log('dataA err is', err)
   * }
   * ......
   * */
 }
})()

如果是这样写只会增加编码的复杂度,而且要多写代码,这个时候就应该想想怎么优雅的解决,async/await 本质就是 promise 的语法糖,既然是 promise 那么就可以使用 then 函数了

(async () => {
 const fetchData = () => {
  return new Promise((resolve, reject) => {
   setTimeout(() => {
    resolve('fetch data is me')
   }, 1000)
  })
 }

 const data = await fetchData().then(data => data ).catch(err => err)
 console.log(data)
})()

在上面写法中,如果 fetchData 返回 resolve 正确结果时,data 是我们要的结果,如果是 reject 了,发生错误了,那么 data 是错误结果,这显然是行不通的,再对其完善。

(async () => {
 const fetchData = () => {
  return new Promise((resolve, reject) => {
   setTimeout(() => {
    resolve('fetch data is me')
   }, 1000)
  })
 }

 const [err, data] = await fetchData().then(data => [null, data] ).catch(err => [err, null])
 console.log('err', err)
 console.log('data', data)
 // err null
 // data fetch data is me
})()

这样是不是好很多了呢,但是问题又来了,不能每个 await 都写这么长,写着也不方便也不优雅,再优化一下

(async () => {
 const fetchData = () => {
  return new Promise((resolve, reject) => {
   setTimeout(() => {
    resolve('fetch data is me')
   }, 1000)
  })
 }

 // 抽离成公共方法
 const awaitWrap = (promise) => {
  return promise
   .then(data => [null, data])
   .catch(err => [err, null])
 }

 const [err, data] = await awaitWrap(fetchData())
 console.log('err', err)
 console.log('data', data)
 // err null
 // data fetch data is me
})()

将对 await 处理的方法抽离成公共的方法,在使用 await 调用 awaitWrap 这样的方法是不是更优雅了呢。如果使用 typescript 实现大概是这个样子

function awaitWrap<T, U = any>(promise: Promise<T>): Promise<[U | null, T | null]> {
 return promise
  .then<[null, T]>((data: T) => [null, data])
  .catch<[U, null]>(err => [err, null])
}

以上。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对三水点靠木的支持。

Javascript 相关文章推荐
javascript 单选框,多选框美化代码
Aug 01 Javascript
js实现身份证号码验证的简单实例
Feb 19 Javascript
jquery 3D 标签云示例代码
Jun 12 Javascript
JavaScript获取网页中第一个图片id的方法
Apr 03 Javascript
JavaScript实现动画打开半透明提示层的方法
Apr 21 Javascript
点评js异步加载的4种方式
Dec 22 Javascript
jQuery实现图像旋转动画效果
May 29 Javascript
Jquery和BigFileUpload实现大文件上传及进度条显示
Jun 27 Javascript
详解能在多种前端框架下使用的表格控件
Jan 11 Javascript
Vue.js基础知识小结
Jan 13 Javascript
jQuery实现ajax回调函数带入参数的方法示例
Jun 26 jQuery
微信小程序出现wx.getLocation再次授权问题的解决方法分析
Jan 16 Javascript
新年快乐! javascript实现超级炫酷的3D烟花特效
Jan 30 #Javascript
JavaScript之解构赋值的理解
Jan 30 #Javascript
JS实现点击按钮随机生成可拖动的不同颜色块示例
Jan 30 #Javascript
JS实现的新闻列表自动滚动效果示例
Jan 30 #Javascript
谈谈为什么你的 JavaScript 代码如此冗长
Jan 30 #Javascript
JS实现头条新闻的经典轮播图效果示例
Jan 30 #Javascript
AJAX在JQuery中的应用详解
Jan 30 #jQuery
You might like
文章推荐系统(三)
2006/10/09 PHP
php&amp;java(三)
2006/10/09 PHP
PHP循环结构实例讲解
2014/02/10 PHP
使用Discuz关键词服务器实现PHP中文分词
2014/03/11 PHP
PHP生成随机码的思路与方法实例探索
2019/04/11 PHP
提高javascript效率 一次判断,而不要次次判断
2012/03/30 Javascript
JavaScript对象属性检查、增加、删除、访问操作实例
2015/07/08 Javascript
分享自己用JS做的扫雷小游戏
2016/02/17 Javascript
jquery ztree实现模糊搜索功能
2016/02/25 Javascript
Bootstrap CSS布局之代码
2016/12/17 Javascript
原生Javascript插件开发实践
2017/01/09 Javascript
js常用DOM方法详解
2017/02/04 Javascript
利用jquery正则表达式在页面验证url网址输入是否正确
2017/04/04 jQuery
javascript使用正则实现去掉字符串前面的所有0
2018/07/23 Javascript
Vue.js中的extend绑定节点并显示的方法
2019/06/20 Javascript
详解微信小程序支付流程与梳理
2019/07/16 Javascript
Swiper.js实现移动端元素左右滑动
2019/09/08 Javascript
Element Tooltip 文字提示的使用示例
2020/07/26 Javascript
Vue左滑组件slider使用详解
2020/08/21 Javascript
原生js实现自定义消息提示框
2020/11/19 Javascript
使用Python的web.py框架实现类似Django的ORM查询的教程
2015/05/02 Python
Python绘制正余弦函数图像的方法
2018/08/28 Python
Python3中的bytes和str类型详解
2019/05/02 Python
bluepy 一款python封装的BLE利器简单介绍
2019/06/25 Python
postman模拟访问具有Session的post请求方法
2019/07/15 Python
python实现的多任务版udp聊天器功能案例
2019/11/13 Python
详解scrapy内置中间件的顺序
2020/09/28 Python
CSS3 Flexbox中flex-shrink属性的用法示例介绍
2013/12/30 HTML / CSS
HTML5 表单验证失败的提示语问题
2017/07/13 HTML / CSS
中国旅游网站:同程旅游
2016/09/11 全球购物
台湾百利市购物中心:e-Payless
2017/08/16 全球购物
我能否用void** 指针作为参数, 使函数按引用接受一般指针
2013/02/16 面试题
药剂学专业应届生自荐信
2013/09/29 职场文书
售后服务承诺书怎么写
2014/05/21 职场文书
在宿舍喝酒的检讨书
2014/09/28 职场文书
派出所正风肃纪剖析材料
2014/10/10 职场文书