在用Promise的时候,可以使用Promise.then().catch()捕获执行结果的错误异常,但是在用多个异步的时候,Promise的嵌套也影响阅读,所以就会用async/await,运用同步的方式来执行异步代码。
对于async/await的异常,可以用try catch来捕获,但是如果一个步骤里有多个await操作,写一大堆try catch属实不美观。
所以github上有大佬写了一个await-to-js,源码只有十几行:
function to<T, U = Error> (
promise: Promise<T>,
errorExt?: object
): Promise<[U, undefined] | [null, T]> {
return promise
.then<[null, T]>((data: T) => [null, data])
.catch<[U, undefined]>((err: U) => {
if (errorExt) {
const parsedError = Object.assign({}, err, errorExt);
return [parsedError, undefined];
}
return [err, undefined];
});
}
其实就是把await后面的Promise用一个函数执行一下,然后在这个函数里把.then()给return出来得到一个新的Promise。新的Promsie的结果是一个数组,用数组第一个元素是否为null来区分原函数是fullfilled还是rejected。
我们自己实现一下,其实就是:
// 原来的Promise
function a(num){
return new Promise((resolve, reject)=>{
if(num<5){
resolve('small'+num)
}else{
reject('big'+num)
}
})
}
// to函数来执行一下a(), to函数返回的是一个Promise
function to(P){
return P.then(data=>{
return [null, data]
}).catch(err=>{
return [err, undefined]; // 因为没有主动抛出异常,所以后续.then是fullfilled的状态
})
}
async function b(){
let b1 = await to(a(8));
console.log(b1); // [ 'big8', undefined ]
let b2 = await to(a(3));
console.log(b2); // [ null, 'small3' ]
}
b();
通过数组的第一个元素是否为null来判断当前是成功还是异常,这样就比try/catch写法上更加简明。