相信大家听过萧亚轩的【最熟悉的陌生人】,整首歌曲流露出一种深深的遗憾,曾经自己认为最熟悉的人,如今陌生的却像路人一样。。。。
言尽于此,回归正题,最近在写一个组件的时候,发现自己曾经认为用的最熟练的 Promise 忽然变得陌生起来,我想这还是由于自身对 Promise 的认知不够导致,所以留下本文,以飨读者。
缘起
引发我重新思考 Promise 用法的是如下一段代码:
new Promise(resolve=>{
console.log('p1');
resolve(1);
}).then(data=>{
console.log('then1');
console.log(data);
throw new Error('error1');
}).catch(err=>{
console.log(err);
return 'error1已处理';
}).then(data=>{
console.log('then2');
console.log(data);
});
我之前的理解是,一旦 Promise 被 catch 捕获并执行之后,后续的 then 或者 catch 都不会再执行。 所以,我的理解程序应该输出如下的结果:
p1
then1
1
Error: error1
at <anonymous>
按照我最初的理解,最后一个 then 不会再执行,但是事实却是执行的,实际打印结果是:
p1
then1
1
Error: error1
at <anonymous>
then2
error1已处理
看来,我还是 too young,too simple
了。
上面这个现象说明了 Promise 的一个用法是,catch 只会捕获到之前 then 的异常, catch 捕获之后,如果之后仍有 then 任务,还是会往后继续执行。
测试
下面几种例子均以两个 then 两个catch,互相衔接。来验证 Promise 的执行机制。
正常执行
new Promise(resolve=>{
console.log('p1');
resolve(1);
}).then(data=>{
console.log('then1');
console.log(data);
return 'then1 返回 2';
//throw new Error('error1');
}).catch(err=>{
console.log('接收then1异常', err);
return 'error1已处理';
}).then(data=>{
console.log('then2');
console.log(data);
}).catch(err=>{
console.log('接收 then2 异常', err);
});
执行过程如下:
结果:
p1
then1
1
then2
then1 返回2
第一个 then 异常。
第一个 then 中抛出异常。
new Promise(resolve=>{
console.log('p1');
resolve(1);
}).then(data=>{
console.log('then1');
console.log(data);
throw new Error('error1');
}).catch(err=>{
console.log('接收then1异常', err);
return 'error1已处理';
}).then(data=>{
console.log('then2');
console.log(data);
}).catch(err=>{
console.log('接收 then2 异常',err);
});
执行过程如下:
结果:
p1
then1
1
接收then1异常 Error: error1
at <anonymous>:7:11
then2
error1已处理
第一个 then 异常、紧接着 catch 异常。
new Promise(resolve=>{
console.log('p1');
resolve(1);
}).then(data=>{
console.log('then1');
console.log(data);
throw new Error('error1');
}).catch(err=>{
console.log('接收then1异常', err);
throw new Error('error1已处理');
}).then(data=>{
console.log('then2');
console.log(data);
}).catch(err=>{
console.log('接收 catch1 异常',err);
});
执行过程如下:
结果:
p1
then1
1
接收then1异常 Error: error1
at <anonymous>:7:11
接收 catch1 异常 Error: error1已处理
at <anonymous>:10:11
总结
综合以上三种常见用法,用四句话简单总结 Promise 机制:
- then 正常接 then。
- then 异常接 catch。
- catch 正常接 then。
- catch 异常接 catch。
简短的一片文章,希望能给大家带来思考,高手可以略过~~ 勿喷~~