前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >async await 的错误处理

async await 的错误处理

作者头像
用户1515472
发布2019-07-24 14:14:54
3K0
发布2019-07-24 14:14:54
举报

async await 从语法层面给人一种非常直观的方式,可以让我们避免 callback hell 与 Promise hell 。

代码语言:javascript
复制
async function getUserInfo() {
	const id = await request.getCurrentId()
	const info = await request.getUserInfo(id)

 	return info
}

但是每一步 await 的都可能出错,为了捕获这些错误,我们使用 try...catch...

代码语言:javascript
复制
async function getUserInfo (cb) {
  try {
     const id = await request.getCurrentId()
  } catch(e) {
     return cb('an error in getCurrentId')
  }
  
  try {
    const info = await request.getUserInfo(id)
  } catch(e) {
    return cb('an error in getUserInfo')
  }

  return cb(null, info)
}

这样写一眼看上去代码异常丑陋而且不直观,国外大神 Dima 在他的文章 how-to-write-async-await-without-try-catch-blocks-in-javascript 中提到了一种解决方案,因为 await 实际上等待的是一个 Promise,因此可以使用一个函数包装一个来符合 error first 的原则,从而避免 try...catch...

代码语言:javascript
复制
function to (promise) {
  return promise.then(data => {
      return [null, data]
  }).catch(err => [err])

}

通过这个函数包装一下上面的例子

代码语言:javascript
复制
async function getUserInfo () {
  let err, id, info; 
  [err, id] = await to(request.getCurrentId())
  if(err) return console.error(err)
  
  [err, info] = await to(request.getUserInfo(id))
  if(err) return console.error(err)

  return info
}

基于这种思路,可以想到直接在每一步 await 的时候都单独 catch, 最后在最外层捕获 error

代码语言:javascript
复制
async function getUserInfo() {
  try {
    const id = await request.getCurrentId().catch(err => Promise.reject('an error in getCurrentId'))
    const info = await request.getUserInfo(id).catch(err => Promise.reject('an error in getUserInfo'))
  } catch(err) {
    errorHandle(err)
  }
}

在实际编码中,我们当然想要一个公共的 error 处理函数,不过如果你的业务太复杂了,偶尔中途需要有额外的处理逻辑也没关系,别忘了 Promise.reject() 啥都可以作为参数:

代码语言:javascript
复制
async function getUserInfo() {
  try {
    const id = await request.getCurrentId().catch(err => Promise.reject('an error in getCurrentId'))
    const info = await request.getUserInfo(id).catch(err => Promise.reject(() => {
    doSomething()
    anotherErrorHandler()
})
  } catch(err) {
    if (typeof err === 'function') err()
    else errorHandle(err)
  }
}

Dima 的处理方式已经很不错了,市面上有非常多的基于这种思想的库,可以在 npm 上 搜索,如果简单拓展下自定义 error 的信息(如code,msg),是否采用 errorFirst 的惯例,如下:

代码语言:javascript
复制
function to (promise, errorProps = {}, errorFirst = true) {
	return promise.then((data) => errorFirst ? [null, data] : [data, null])
			  .catch(err => {
				  if(errorProps) Object.assign(err, errorProps)
				  errorFirst ? [err, undefined] : [undefined, err]
			  })
  }

大概关于 async await 的错误处理就总结如上了,以后遇到更好地处理方式再说。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档