一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第20天,点击查看活动详情。
问题: await Promise, 只能接收到成功的 resolve() 的结果
, 对于 reject() 的结果会报错。
解决办法: try-catch
来处理同步逻辑
function test () {
return new Promise((resolve, reject) => {
this.$axios("请求地址").then((res) => {
if (res.data.status === 200) {
resolve(res.data.result) // 请求成功会回调
} else {
reject("err") // 请求失败会回调
}
})
})
}
async fun () {
try {
cosnt testRes = await this.test()
console.log(testRes)
} catch (err) {
console.log(err) // 请求错误会执行,结果为 err
}
}
更优雅的解决方式 await-to-js
如果只有1个请求,try catch倒是不错。但是如果有多个异步操作,需要对每个异步返回的 error 错误状态进行不同的处理,项目将会大量充斥着try catch
,这就比较令人难以接受了。
function request(type) {
return new Promise((resolve, reject) => {
setTimeout(() => {
type === 'a' ? resolve('resolve') : reject('reject')
}, 2000);
})
}
async function getData() {
try {
let ret1 = await request('a');
}catch(error){
// todo
}
try {
let ret2 = await request('b');
} catch (error) {
// todo
}
try {
let ret3 = await request('c');
} catch (error) {
// todo
}
}
getData();
在复杂的业务中,这种充斥很多的try catch
实在不够简洁。势必会想办法解决一下这个问题。 首先需要明确的是 await
后面的promise
只有是一个resolve
状态,才能正确的拿到其结果。那么要解决这个问题,势必要让异步返回一个resolve
状态,但是错误我们不能视而不见,结合nodejs
中错误优先,我们可以将错误和结果封装成一个数组返回,那么就有了await-to-js
await-to-js源码
源码总结: to
函数返回一个Promise且值是一个数组,数组之中有两个元素,如果索引为0
的元素不为空值,说明该请求报错,如果索引0
的元素为空值说明该请求没有报错,也就是成功。
/**
* @param { Promise } 传进去的请求函数
* @param { Object= } errorExt - 拓展错误对象
* @return { Promise } 返回一个Promise
*/
export function to(
promise,
errorExt
) {
return promise
.then(data => [null, data])
.catch(err => {
if (errorExt) {
const parsedError = Object.assign({}, err, errorExt)
return [parsedError, undefined]
}
return [err, undefined]
})
}
export default to
使用
const handleLogin = async () => {
const [resErr, res] = await to(request('/basic/login', {
usename: 'sunshine',
password: '123456'
}))
if (resErr) {
// fail do somthing
return
}
const [userErr, info] = await to(request('/basic/getuserinfo', {
id: res.id
}))
if (userErr) {
// fail do somthing
return
}
this.userInfo = info
}