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 load Page,load css,load js实现代码
Mar 31 Javascript
imgAreaSelect 中文文档帮助说明
Oct 08 Javascript
Javascript 面向对象(二)封装代码
May 23 Javascript
JavaScript高级程序设计 阅读笔记(十三) js定义类或对象
Aug 14 Javascript
jQuery中each()方法用法实例
Dec 27 Javascript
jquery使用animate方法实现控制元素移动
Mar 27 Javascript
JavaScript制作淘宝星级评分效果的思路
Jun 23 Javascript
关于获取DIV内部内容报错的原因分析及解决办法
Jan 29 Javascript
Ajax分页插件Pagination从前台jQuery到后端java总结
Jul 22 Javascript
angularjs实现的购物金额计算工具示例
May 08 Javascript
ajaxfileupload.js实现上传文件功能
Apr 19 Javascript
vue实现移动端轻量日期组件不依赖第三方库的方法
Apr 28 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
php生成数字字母的验证码图片
2015/07/14 PHP
javascript 打印页面代码
2009/03/24 Javascript
IE中createElement需要注意的一个问题
2010/07/13 Javascript
jQuery实现类似淘宝购物车全选状态示例
2013/06/26 Javascript
JavaScript用JQuery呼叫Server端方法示例代码
2014/09/03 Javascript
JavaScript获取一个范围内日期的方法
2015/04/24 Javascript
js实现简洁的滑动门菜单(选项卡)效果代码
2015/09/04 Javascript
解决js函数闭包内存泄露问题的办法
2016/01/25 Javascript
JS+CSS实现鼠标经过弹出一个DIV框完整实例(带缓冲动画渐变效果)
2016/03/25 Javascript
微信js-sdk界面操作接口用法示例
2016/10/12 Javascript
读Javascript高性能编程重点笔记
2016/12/21 Javascript
angularjs过滤器--filter与ng-repeat配合有奇效
2017/04/20 Javascript
JS原生数据双向绑定实现代码
2017/08/14 Javascript
AngularJS自定义表单验证功能实例详解
2018/08/24 Javascript
微信小程序实现滑动切换自定义页码的方法分析
2018/12/29 Javascript
微信小程序实现简易table表格
2020/06/19 Javascript
Vue中UI组件库之Vuex与虚拟服务器初识
2019/05/07 Javascript
Element Notification通知的实现示例
2020/07/27 Javascript
JavaScript实现通讯录功能
2020/12/27 Javascript
Python脚本在Appium库上对移动应用实现自动化测试
2015/04/17 Python
浅谈python中列表、字符串、字典的常用操作
2017/09/19 Python
python实现简易通讯录修改版
2018/03/13 Python
python用类实现文章敏感词的过滤方法示例
2019/10/27 Python
python标识符命名规范原理解析
2020/01/10 Python
HTML5安全介绍之内容安全策略(CSP)简介
2012/07/10 HTML / CSS
手摸手教你用canvas实现给图片添加平铺水印的实现
2019/08/20 HTML / CSS
中国领先的专业演出票务网:永乐票务
2016/08/29 全球购物
西尔斯百货官网:Sears
2016/09/06 全球购物
Sql面试题
2013/03/20 面试题
2014年党员创先争优承诺书
2014/05/29 职场文书
受伤赔偿协议书
2014/09/24 职场文书
2014年煤矿工人工作总结
2014/12/08 职场文书
党员年终个人总结
2015/02/14 职场文书
Python list去重且保持原顺序不变的方法
2021/04/03 Python
java设计模式--三种工厂模式详解
2021/07/21 Java/Android
MySQL中varchar和char类型的区别
2021/11/17 MySQL