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日期选择自动填充到输入框(界面漂亮兼容火狐)
Aug 02 Javascript
jquery自动切换tabs选项卡的具体实现
Dec 24 Javascript
Javascript数组与字典用法分析
Dec 13 Javascript
Node.js实现批量去除BOM文件头
Dec 20 Javascript
JS对象是否拥有某属性如何判断
Feb 03 Javascript
jquery uploadify隐藏上传进度的实现方法
Feb 06 Javascript
详解JavaScript中return的用法
May 08 Javascript
深入理解JavaScript创建对象的多种方式以及优缺点
Jun 01 Javascript
AngularJS基于http请求实现下载php生成的excel文件功能示例
Jan 23 Javascript
微信小程序实现点赞、取消点赞功能
Nov 02 Javascript
vue2 v-model/v-text 中使用过滤器的方法示例
May 09 Javascript
一分钟学会JavaScript中的try-catch
Dec 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
基于php 随机数的深入理解
2013/06/05 PHP
php把session写入数据库示例
2014/02/26 PHP
彻底删除thinkphp3.1案例blog标签的方法
2014/12/05 PHP
PHP基于PDO扩展操作mysql数据库示例
2018/12/24 PHP
PHP标准库 (SPL)――Countable用法示例
2020/06/05 PHP
PHP xpath提取网页数据内容代码解析
2020/07/16 PHP
$.format,jquery.format 使用说明
2011/07/13 Javascript
url参数中有+、空格、=、%、&amp;、#等特殊符号的问题解决
2013/05/15 Javascript
JavaScript改变HTML元素的样式改变CSS及元素属性
2013/11/12 Javascript
jquery获取当前点击对象的value方法
2014/02/28 Javascript
JavaScript中的函数的两种定义方式和函数变量赋值
2014/05/12 Javascript
关于Jquery中的bind(),on()绑定事件方式总结
2016/10/26 Javascript
ES6中module模块化开发实例浅析
2017/04/06 Javascript
详解React之父子组件传递和其它一些要点
2018/06/25 Javascript
webpack中的模式(mode)使用详解
2020/02/20 Javascript
[05:28]刀塔密之一:团结则存
2014/07/03 DOTA
[01:56]无止竞 再出发——中国军团出征2017年DOTA2国际邀请赛
2017/07/05 DOTA
[49:27]2018DOTA2亚洲邀请赛 4.4 淘汰赛 TNC vs VG 第一场
2018/04/05 DOTA
[47:45]DOTA2-DPC中国联赛 正赛 Phoenix vs Dragon BO3 第一场 2月26日
2021/03/11 DOTA
python 正则式使用心得
2009/05/07 Python
Python基于Tkinter实现的记事本实例
2015/06/17 Python
windows下Python实现将pdf文件转化为png格式图片的方法
2017/07/21 Python
python+opencv实现的简单人脸识别代码示例
2017/11/14 Python
Python使用matplotlib绘制正弦和余弦曲线的方法示例
2018/01/06 Python
Python中的二维数组实例(list与numpy.array)
2018/04/13 Python
python3+PyQt5实现柱状图
2018/04/24 Python
使用pycharm设置控制台不换行的操作方法
2019/01/19 Python
Python画图实现同一结点多个柱状图的示例
2019/07/07 Python
PyCharm 配置远程python解释器和在本地修改服务器代码
2019/07/23 Python
Python下划线5种含义代码实例解析
2020/07/10 Python
阿迪达斯奥地利官方商城:adidas.at
2016/10/16 全球购物
计划生育证明格式及范本
2014/10/09 职场文书
综治工作汇报材料
2014/10/27 职场文书
2015年乡镇工会工作总结
2015/05/19 职场文书
七年级作文之英语老师
2019/10/28 职场文书
Python合并多张图片成PDF
2021/06/09 Python