async await 的错误处理
async await 从语法层面给人一种非常直观的方式,可以让我们避免 callback hell 与 Promise hell 。
async function getUserInfo() { const id = await request.getCurrentId() const info = await request.getUserInfo(id) return info }
但是每一步 await 的都可能出错,为了捕获这些错误,我们使用 try...catch...
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...
function to (promise) { return promise.then(data => { return [null, data] }).catch(err => [err]) }
通过这个函数包装一下上面的例子
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
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()
啥都可以作为参数:
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 的惯例,如下:
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
的错误处理就总结如上了,以后遇到更好地处理方式再说。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
上一篇: 带标签的模板字符串
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论