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 相关文章推荐
JXTree对象,读取外部xml文件数据,生成树的函数
Apr 02 Javascript
js的Prototype属性解释及常用方法
May 08 Javascript
angular简介和其特点介绍
Jan 29 Javascript
JavaScript中Cookies的相关使用教程
Jun 04 Javascript
深入理解事件冒泡(Bubble)和事件捕捉(capture)
May 28 Javascript
浅谈键盘上回车按钮的js触发事件
Feb 13 Javascript
vue2.0父子组件间传递数据的方法
Aug 16 Javascript
玩转Koa之核心原理分析
Dec 29 Javascript
微信小程序上传多图到服务器并获取返回的路径
May 05 Javascript
微信小程序使用 vant Dialog组件的正确方式
Feb 21 Javascript
vue 实现锚点功能操作
Aug 10 Javascript
JavaScript日期库date-fn.js使用方法解析
Sep 09 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
压力如何影响浓缩咖啡品质
2021/03/03 咖啡文化
php文件压缩之PHPZip类用法实例
2015/06/18 PHP
php采集神器cURL使用方法详解
2016/02/19 PHP
PDO::beginTransaction讲解
2019/01/27 PHP
转一个日期输入控件,支持FF
2007/04/27 Javascript
jquery 循环显示div的示例代码
2013/10/18 Javascript
深入理解jQuery之防止冒泡事件
2016/05/24 Javascript
jQuery实现jQuery-form.js实现异步上传文件
2017/04/28 jQuery
详解vue-cli 本地开发mock数据使用方法
2018/05/29 Javascript
vue实现添加与删除图书功能
2018/10/07 Javascript
关于js陀螺仪的理解分析
2019/04/11 Javascript
JS实现的tab切换并显示相应内容模块功能示例
2019/08/03 Javascript
基于vue实现图片验证码倒计时60s功能
2019/12/10 Javascript
如何HttpServletRequest文件对象并储存
2020/08/14 Javascript
11个并不被常用但对开发非常有帮助的Python库
2015/03/31 Python
在Python 3中实现类型检查器的简单方法
2015/07/03 Python
python+matplotlib实现礼盒柱状图实例代码
2018/01/16 Python
python2.7到3.x迁移指南
2018/02/01 Python
python实现list由于numpy array的转换
2018/04/04 Python
opencv python在视屏上截图功能的实现
2020/03/05 Python
详解CSS3 rem(设置字体大小) 教程
2017/11/21 HTML / CSS
简洁自适应404页面HTML好看的404源码
2020/12/16 HTML / CSS
原装进口全世界:天猫国际
2016/08/03 全球购物
分解成质因数(如435234=251*17*17*3*2,据说是华为笔试题)
2014/07/16 面试题
测试驱动开发的主要步骤是什么
2014/12/10 面试题
大学生校园创业计划书
2014/02/08 职场文书
会计电算化学生个人的自我评价
2014/02/08 职场文书
学习雷锋精神心得体会范文
2014/03/12 职场文书
升国旗仪式主持词
2014/03/19 职场文书
银行职员自我鉴定
2014/04/20 职场文书
审计局2014法制宣传日活动总结
2014/11/01 职场文书
物业工程部主管岗位职责
2015/04/16 职场文书
2015年暑期社会实践方案
2015/07/14 职场文书
Windows Server 2019 配置远程控制以及管理方法
2022/04/28 Servers
tomcat正常启动但网页却无法访问的几种解决方法
2022/05/06 Servers
python标准库ElementTree处理xml
2022/05/20 Python