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中,为什么要尽可能使用局部变量?
Apr 06 Javascript
JS中confirm,alert,prompt函数使用区别分析
Apr 01 Javascript
js控制href内容的连接内容的变化示例
Apr 30 Javascript
深入理解JavaScript系列(29):设计模式之装饰者模式详解
Mar 03 Javascript
jQuery中队列queue()函数的实例教程
May 03 Javascript
js无提示关闭浏览器窗口的两种方法分析
Nov 06 Javascript
JS中静态页面实现微信分享功能
Feb 06 Javascript
javascript 初学教程及五子棋小程序的简单实现
Jul 04 Javascript
JavaScript使用FileReader实现图片上传预览效果
Mar 27 Javascript
jquery select插件异步实时搜索实例代码
Oct 20 jQuery
webpack多页面开发实践
Dec 18 Javascript
vue2.0中set添加属性后视图不能更新的解决办法
Feb 22 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 Undefined index报错的修复方法
2011/07/17 PHP
php读取csc文件并输出
2015/05/21 PHP
分享php代码将360浏览器导出的favdb的sqlite数据库文件转换为html
2015/12/09 PHP
PHP QRCODE生成彩色二维码的方法
2016/05/19 PHP
Laravel Validator自定义错误返回提示消息并在前端展示
2019/05/09 PHP
Javascript继承机制的设计思想分享
2011/08/28 Javascript
node在两个div之间移动,用ztree实现
2013/03/06 Javascript
js函数定时器实现定时读取系统实时连接数
2014/04/30 Javascript
在 Express 中使用模板引擎
2015/12/10 Javascript
jQuery zTree加载树形菜单功能
2016/02/25 Javascript
20行JS代码实现网页刮刮乐效果
2017/06/23 Javascript
详解React中的组件通信问题
2017/07/31 Javascript
JS数组操作之增删改查的简单实现
2017/08/21 Javascript
关于Promise 异步编程的实例讲解
2017/09/01 Javascript
JavaScript实现的原生态Tab标签页功能【兼容IE6】
2017/09/18 Javascript
node.js实现简单的压缩/解压缩功能示例
2019/11/05 Javascript
vue2.x 对象劫持的原理实现
2020/04/19 Javascript
[01:50]WODOTA制作 DOTA2中文宣传片《HERO》
2013/04/28 DOTA
Python设计模式之工厂模式简单示例
2018/01/09 Python
pytorch 实现模型不同层设置不同的学习率方式
2020/01/06 Python
Python更改pip镜像源的方法示例
2020/12/01 Python
Python结合百度语音识别实现实时翻译软件的实现
2021/01/18 Python
英国足球店:UK Soccer Shop
2017/11/19 全球购物
英国最大的正宗复古足球衫制造商和零售商:TOFFS
2018/06/21 全球购物
商务日语毕业生自荐信
2013/11/23 职场文书
《狮子和兔子》教学反思
2014/03/02 职场文书
党员干部2014全国两会学习心得体会
2014/03/10 职场文书
超市促销活动总结
2014/07/01 职场文书
大班上学期个人总结
2015/02/13 职场文书
重阳节慰问信
2015/02/15 职场文书
培训感想范文
2015/08/07 职场文书
2015教师个人年度工作总结
2015/10/23 职场文书
读《庄子》有感:美而不自知
2019/11/06 职场文书
JavaScript 原型与原型链详情
2021/11/02 Javascript
Javascript的promise,async和await的区别详解
2022/03/24 Javascript
5人制售《绝地求生》游戏外挂获利500多万元 被判刑
2022/03/31 其他游戏