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与C# Windows应用程序交互方法
Jun 29 Javascript
Prototype Selector对象学习
Jul 23 Javascript
extJS中常用的4种Ajax异步提交方式
Mar 07 Javascript
js+csss实现的一个带复选框的下拉框
Sep 29 Javascript
jQuery无刷新切换主题皮肤实例讲解
Oct 21 Javascript
深入理解Node.js 事件循环和回调函数
Nov 02 Javascript
EasyUI 中combotree 默认不能选择父节点的实现方法
Nov 07 Javascript
JS获取年月日时分秒的方法分析
Nov 28 Javascript
JavaScript中利用构造器函数模拟类的方法
Feb 16 Javascript
JS条形码(一维码)插件JsBarcode用法详解【编码类型、参数、属性】
Apr 19 Javascript
Vue.js递归组件构建树形菜单
Dec 24 Javascript
Node.js assert断言原理与用法分析
Jan 04 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/09/29 PHP
PHP简单判断手机设备的方法
2016/08/23 PHP
几个常用的JavaScript字符串处理函数 - split()、join()、substring()和indexOf()
2009/06/02 Javascript
让Firefox支持event对象实现代码
2009/11/07 Javascript
微博@符号的用户名提示效果。(想@到谁?)
2010/11/05 Javascript
仿中关村在线首页弹出式广告插件(jQuery版)
2012/05/03 Javascript
js如何获取file控件的完整路径具体实现代码
2013/05/15 Javascript
js setTimeout 常见问题小结
2013/08/13 Javascript
jquery统计输入文字的个数并对其进行判断
2014/01/07 Javascript
简介JavaScript中toTimeString()方法的使用
2015/06/12 Javascript
JS简单实现表格排序功能示例
2016/12/20 Javascript
javascript 中关于array的常用方法详解
2017/05/05 Javascript
Angular.js ng-file-upload结合springMVC的使用教程
2017/07/10 Javascript
Vuex实现计数器以及列表展示效果
2018/03/10 Javascript
Vue axios全局拦截 get请求、post请求、配置请求的实例代码
2018/11/28 Javascript
vue 实现通过vuex 存储值 在不同界面使用
2019/11/11 Javascript
详解javascript void(0)
2020/07/13 Javascript
[05:31]DOTA2英雄梦之声_第08期_莉娜
2014/06/23 DOTA
理解Python中函数的参数
2015/04/27 Python
在ironpython中利用装饰器执行SQL操作的例子
2015/05/02 Python
python使用threading获取线程函数返回值的实现方法
2017/11/15 Python
python复制列表时[:]和[::]之间有什么区别
2018/10/16 Python
python实现微信自动回复及批量添加好友功能
2019/07/03 Python
python之拟合的实现
2019/07/19 Python
Python pickle模块实现对象序列化
2019/11/22 Python
Cython编译python为so 代码加密示例
2019/12/23 Python
美国领先的奢侈手表在线零售商:WatchMaxx
2017/12/17 全球购物
牵手50新加坡:专为黄金岁月的单身人士而设的交友网站
2020/08/16 全球购物
Burt’s Bees英国官网:世界领先的天然个人护理品牌
2020/08/17 全球购物
办公文员的工作岗位职责
2013/11/12 职场文书
新学期班主任寄语
2014/01/18 职场文书
科学发展观演讲稿
2014/09/11 职场文书
学会感恩主题班会
2015/08/12 职场文书
2019入党申请书格式
2019/06/25 职场文书
nginx反向代理时如何保持长连接
2021/03/31 Servers
python3读取文件指定行的三种方法
2021/05/24 Python