Promise及Es6Async Await 如何异常捕获?

上篇文章介绍了Promise和Async Await有什么区别(可以点击这里),Async Await是Promise的进化版,但是它的本质还是Promise,所以要想学好Async Await 必须先精通Promise!好了,废话不多说,今天接着上次没说完的话题,介绍Promise及Async Await 如何异常捕获?


一、Promise
  1. promise(实例).then后面第二个参数可以捕获到异常。
let promise = new Promise((resolve, reject) => {
     reject('错误');
 });


 promise.then(() => {}, (error) => {
     console.log(error); //'错误'
 });
  1. promise(实例).catch也可以捕获到异常
let promise = new Promise((resolve, reject) => {
    reject('错误');
});


promise.catch((error) => {
    console.log(error);
});
  1. 两者有什么区别?我们用代码一个一个验证再下结论!
let promise = new Promise((resolve, reject) => {
    reject('失败');
});

promise.then(() => {

}, (err) => {
   
}).catch((err) => {
    console.log(err);//这里没有执行
});
--------------------------------------------
promise.then(() => {

}, (err) => {
    console.log(err); //失败
}).catch((err) => {
    console.log(err);//这里没有执行
});

--------------------------------------------
promise.then(() => {

}).catch((err) => {
    console.log(err);//失败
}).then(() => {
    
}, (err) => {
    console.log(err)//这里没有执行
});

结论: then 第二个参数和catch 是有优先级关系的,写在前面的先捕获,后面就没有错误可以捕获了。

let promise = new Promise((resolve, reject) => {
    reject('失败');
});
promise.then(() => {

}, (err) => {
   //默认执行 return Promise.resolve();
}).catch((err) => {
    console.log(err); //这里没有执行
}).then(() => {
    console.log('我会执行')
});

结论:为什么会有优先级关系? 因为then 第二个参数(或者第一个参数或者catch)默认返回了一个新的Fulfilled的状态的Promise,等同于return Promise.resolve(),所以后面的then会执行,而catch就不会执行了

let promise = new Promise((resolve, reject) => {
    reject('失败');
});

promise.then(() => {

}, (err1) => {
    return promise1;
}).then(() => {

}, (err2) => {
    console.log(err2); //ReferenceError: promise1 is not defined
    return promise2;
}).then(() => {

}, (err3) => {
    console.log(err3); //ReferenceError: promise2 is not defined
});
------------------------------------------
promise.then(() => {

}, (err1) => {
    return promise1;
}).then(() => {

}).catch((err3) => {
    console.log(err3); //ReferenceError: promise1 is not defined
});
-------------------------------------------
promise.then(() => {

}, (err1) => {

}).then(() => {
    return promise1;
}).catch((err3) => {
    console.log(err3); //ReferenceError: promise1 is not defined
});

结论:catch 写法是针对于整个链式写法的错误而捕获的,而 then的第二个参数是针对于上一个返回的 Promise 的。所以我们平时写代码尽量用catch去捕获异常

let promise = new Promise((resolve, reject) => {
    reject('失败');
});
promise.then(() => {
   
}, (err1) => {
   return promise1;
}).then(() => {
//这里不会执行,直接跑下个then
}).then(undefined, (err3) => {
    console.log(err3); //ReferenceError: promise1 is not defined
});
//等价于
promise.then(() => {
  
}, (err1) => {
  return promise1;
}).then(undefined, (err3) => {
   console.log(err3); //ReferenceError: promise1 is not defined
});
//这就是catch能捕获整个链式写法的错误,而then的第二个参数只能捕获到上一个返回的Promise的错误!

结论: catch() 方法返回一个Promise,并且处理拒绝的情况。它的行为与调用Promise.then(undefined, onRejected) 相同

 //一道promise 值穿透的面试题,
 Promise.resolve(1).then(2).then(console.log); //1

结论: 当then传的值不是一个函数的时候,就将值传递给下一个then,也叫做值穿透,不懂的话可以看promise源码怎么执行的,大概是这样,判断一下callback是否是函数,如果不是函数,就将上一层的值赋值给value,相当是return Promise.resolve(value)实现了所说的值穿透,请原谅我又跑题了!下面说下Async Await!

二、Async Await
  1. async函数返回的是一个Promise,所以我们可以在外面catch住错误。
async function test() {
    await new Promise((resolve, reject) => reject('错误'));
};
test().catch((data) => console.log(data)); //错误
  1. 你不想在外面catch,你可以在函数内部可以使用try...catch语句。
async function test() {
    try {
        await new Promise((resolve, reject) => reject('错误'));
    } catch (error) {
        console.log(error); //错误
    };
};
test();
  1. await 后面跟着的肯定是一个Promise,也可以在Promise后面catch。
async function test() {
     await new Promise((resolve, reject) => reject('错误')).catch((data) => console.log(data));
     await new Promise((resolve, reject) => reject('错误1')).catch((data) => console.log(data));
     await new Promise((resolve, reject) => reject('错误2')).catch((data) => console.log(data));
 };
 test(); //错误,错误1,错误2
  1. 可以在上面的写法基础上,我们可以优化一下,封装下提取错误函数。
let promiseValue = (promise) => {
    return promise.then((data) => [null, data]).catch((err) => [err]);
};
async function test() {
    [err, data] = await promiseValue(new Promise((resolve, reject) => reject('错误')));
    if (err) console.log(err);
    [err1, data1] = await promiseValue(new Promise((resolve, reject) => reject('错误1')));
    if (err1) console.log(err1);
    [err2, data2] = await promiseValue(new Promise((resolve, reject) => reject('错误2')));
    if (err2) console.log(err2);
};
test();//错误,错误1,错误2
  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值