如何优雅处理 async/await 中的错误?
程序员文章站
2022-06-15 13:46:04
...
我们都知道 async/await 是 promise 的语法糖。
// 模拟请求接口, 返回的是 Promise 对象.
const request = success => {
// 请求耗时 0 ~ 2 秒
const wait = Math.random() * 2000
console.log('请求时间', wait)
return new Promise((resolve, reject) => {
setTimeout(() => {
success ? resolve('ok') : reject('fail')
}, wait)
})
}
promise 使用 then 方法和 catch 方法处理
request(true).then(res => {
console.log('res', res)
}).catch(err => {
console.log('err', err)
})
使用 async/await 优化
(async () => {
const res = await request(true)
console.log('res', res)
})()
当 success 参数为 false 时
(async () => {
const res = await request(false)
console.log('res', res)
})()
报错如下:
像上面这样的写法,async/await 无法处理抛出的错误和 reject 的内容
第一种解决方案 :
(async () => {
const res = await request(false).catch(err => console.log('err', err))
console.log('res', res)
})()
第二种解决方案:
(async () => {
try {
const res = await request(false)
console.log('res', res)
} catch(err) {
console.log('err', err)
}
})()
第一种解决方案利用使用的 catch 方法,第二种解决方案使用 try catch 以上两种方法都可以解决,但是不够优雅,因为当有多个异步操作时需要写成:
方案一:
(async () => {
const resA = await request(false).catch(errA => console.log('errA', errA))
const resB = await request(false).catch(errB => console.log('errB', errB))
const resC = await request(false).catch(errC => console.log('errC', errC))
// ...
})()
方案二(1):
(async () => {
try {
const resA = await request(false)
} catch(errA) {
// ...错误处理
console.log('errA', errA)
}
try {
const resB = await request(false)
} catch(errB) {
// ...错误处理
console.log('errB', errB)
}
try {
const resC = await request(false)
} catch(errC) {
// ...错误处理
console.log('errC', errC)
}
try {
// ...
} catch(errX) {}
})()
方案二(2):
(async () => {
try {
const resA = await request(false)
const resB = await request(false)
const resC = await request(false)
} catch(err) {
if (err.type === 'errA') {
// 错误处理
} else if (err.type === 'errB') {
// 错误处理
}
}
})()
以上两种方案在异步处理数量多的情况下,会显得更加复杂,似乎对不起语法糖这个称号。有没有一种方法可以优雅处理 async/await 中的错误? 答案是有的。
// 抽离成公共方法
const awaitWrap = promise => {
return promise
.then(res => [null, res])
.catch(err => [err, null])
}
(async () => {
const [err, res] = await awaitWarp(request(false))
console.log('res', res) // null
console.log('err', err) // err fail
})()