熟悉又陌生的【Promise】

229 阅读3分钟

相信大家听过萧亚轩的【最熟悉的陌生人】,整首歌曲流露出一种深深的遗憾,曾经自己认为最熟悉的人,如今陌生的却像路人一样。。。。

言尽于此,回归正题,最近在写一个组件的时候,发现自己曾经认为用的最熟练的 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。

简短的一片文章,希望能给大家带来思考,高手可以略过~~ 勿喷~~