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 相关文章推荐
一个JS翻页效果
Jul 23 Javascript
jquery控制listbox中项的移动并排序
Nov 12 Javascript
下载网站打开页面后间隔多少时间才显示下载链接地址的代码
Apr 25 Javascript
js每隔5分钟执行一次ajax请求的实现方法
Nov 27 Javascript
jQuery中 prop() attr()使用详解
May 19 Javascript
跟我学习javascript的call(),apply(),bind()与回调
Nov 16 Javascript
简单实现js选项卡切换效果
Feb 03 Javascript
jQuery bt气泡实现悬停显示及移开隐藏功能的方法
Jul 12 Javascript
js模态对话框使用方法详解
Feb 16 Javascript
完美实现js选项卡切换效果(一)
Mar 08 Javascript
Javascript实现从小到大的数组转换成二叉搜索树
Jun 13 Javascript
JS对象与json字符串相互转换实现方法示例
Jun 14 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
实用函数5
2007/11/08 PHP
Zend studio文件注释模板设置方法
2013/09/29 PHP
Zend Framework教程之Resource Autoloading用法实例
2016/03/08 PHP
PHP实现清除MySQL死连接的方法
2016/07/23 PHP
PHP使用strrev翻转中文乱码问题的解决方法
2017/01/13 PHP
一段好玩的JavaScript代码
2006/12/01 Javascript
JavaScript的面向对象方法以及差别
2008/03/31 Javascript
ajax更新数据后,jquery、jq失效问题
2011/03/16 Javascript
JavaScript判断一个URL链接是否有效的实现方法
2011/10/08 Javascript
jquery(live)中File input的change方法只起一次作用的解决办法
2011/10/21 Javascript
JavaScript设计模式之外观模式实例
2014/10/10 Javascript
浅析ES6的八进制与二进制整数字面量
2016/08/30 Javascript
javascript加载xml 并解析各节点的值(实现方法)
2016/10/12 Javascript
easyui datebox 时间限制,datebox开始时间限制结束时间,datebox截止日期比起始日期大的实现代码
2017/01/12 Javascript
深入理解ES6的迭代器与生成器
2017/08/19 Javascript
ES6之模版字符串的具体使用
2018/05/17 Javascript
微信小程序自定义菜单切换栏tabbar组件代码实例
2019/12/30 Javascript
vue中利用iscroll.js解决pc端滚动问题
2020/02/15 Javascript
tensorflow 恢复指定层与不同层指定不同学习率的方法
2018/07/26 Python
numpy ndarray 取出满足特定条件的某些行实例
2019/12/05 Python
如何基于Python实现数字类型转换
2020/02/07 Python
python模式 工厂模式原理及实例详解
2020/02/11 Python
使用CSS3实现多列布局与多背景的技巧
2016/02/29 HTML / CSS
html特殊符号示例 html特殊字符编码对照表
2014/01/14 HTML / CSS
美国最大的高尔夫发球时间预订网站:TeeOff.com
2018/03/28 全球购物
毕业生个人求职信范例分享
2013/12/17 职场文书
销售找工作求职信
2013/12/20 职场文书
三查三看党性分析材料
2014/02/18 职场文书
结婚周年感言
2014/02/24 职场文书
俞敏洪北大演讲稿
2014/05/22 职场文书
动漫设计与制作专业推荐信
2014/07/07 职场文书
聘用合同范本
2015/09/21 职场文书
Python+Appium实现自动抢微信红包
2021/05/21 Python
html中显示特殊符号(附带特殊字符对应表)
2021/06/21 HTML / CSS
详解SpringBoot异常处理流程及原理
2021/06/21 Java/Android
一篇文章弄懂Python关键字、标识符和变量
2021/07/15 Python