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 相关文章推荐
更正确的asp冒泡排序
May 24 Javascript
javascript+xml技术实现分页浏览
Jul 27 Javascript
window.open的页面如何刷新(父页面)上层页面
Dec 28 Javascript
Window.Open如何在同一个标签页打开
Jun 20 Javascript
JSONP之我见
Mar 24 Javascript
js window对象属性和方法相关资料整理
Nov 11 Javascript
javascript日期格式化方法小结
Dec 17 Javascript
AngularJS  ng-table插件设置排序
Sep 21 Javascript
微信小程序  audio音频播放详解及实例
Nov 02 Javascript
js将当前时间格式化为 年-月-日 时:分:秒的实现代码
Jan 20 Javascript
JS选取DOM元素常见操作方法实例分析
Dec 10 Javascript
JS如何监听div的resize事件详解
Dec 03 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+.htaccess实现全站静态HTML文件GZIP压缩传输(一)
2007/02/15 PHP
浅析php面向对象public private protected 访问修饰符
2013/06/30 PHP
php调用MySQL存储过程的方法集合(推荐)
2013/07/03 PHP
php返回json数据函数实例
2014/10/09 PHP
转一个日期输入控件,支持FF
2007/04/27 Javascript
JavaScript 函数replace深入了解
2013/03/14 Javascript
js数组转json并在后台对其解析具体实现
2013/11/20 Javascript
Jquery性能优化详解
2014/05/15 Javascript
jQuery+AJAX实现网页无刷新上传
2015/02/22 Javascript
jQuery实现的分页功能示例
2017/01/22 Javascript
jQuery实现简单弹窗遮罩效果
2017/02/27 Javascript
详解vue2.0脚手架的webpack 配置文件分析
2017/05/27 Javascript
javascript 缓冲运动框架的实现
2017/09/29 Javascript
iview table高度动态设置方法
2018/03/14 Javascript
Vue2实时监听表单变化的示例讲解
2018/08/30 Javascript
JavaScript实现星级评价效果
2019/05/17 Javascript
js实现GIF动图分解成多帧图片上传
2019/10/24 Javascript
[03:12]完美世界DOTA2联赛PWL DAY6集锦
2020/11/05 DOTA
Python实现把json格式转换成文本或sql文件
2015/07/10 Python
Python ldap实现登录实例代码
2016/09/30 Python
python爬虫之自动登录与验证码识别
2020/06/15 Python
Python3 Post登录并且保存cookie登录其他页面的方法
2018/12/28 Python
用scikit-learn和pandas学习线性回归的方法
2019/06/21 Python
python创建n行m列数组示例
2019/12/02 Python
nginx搭建基于python的web环境的实现步骤
2020/01/03 Python
HTML5自定义属性前缀data-及dataset的使用方法(html5 新特性)
2017/08/24 HTML / CSS
说出数据连接池的工作机制是什么?
2013/04/19 面试题
意向书范本
2014/07/29 职场文书
2014领导班子四风问题查摆思想汇报
2014/09/13 职场文书
2014年党员自我评议对照检查材料
2014/09/20 职场文书
2015年财务个人工作总结范文
2015/05/22 职场文书
奖学金主要事迹范文
2015/11/04 职场文书
数学复习课教学反思
2016/02/18 职场文书
股东协议书范本2016
2016/03/21 职场文书
街道办残联2016年助残日活动总结
2016/04/01 职场文书
MySQL中存储时间的最佳实践指南
2021/07/01 MySQL