一道有意思并对你有协助的Promise题

一道有意思的题

以下我的进修剖析心路历程,以及我本身又多加了几道菜;愿望对你有协助

先上菜

new Promise((resolve, reject) => {
    console.log('promise1');
    resolve();
}).then(() => {
    console.log('then11');
    new Promise((resolve, reject) => {
        console.log('promise2');
        resolve();
    }).then(() => {
        console.log('then21');
    }).then(() => {
        console.log('then23');
    });
}).then(() => {
    console.log('then12');
});

剖析第一道菜

  • 第一次看到我做错了,答案是
promise1
then11
promise2
then21
then12
then23
  • 我的迷惑就是then12为何在then21then23之间,很新鲜。申明什么呢?我对Promise的内部完成还不相识,那只能去看源码了。在进修过程当中,本身也尝试转变了几处,也贴上来吧,人人看看

看完后我的明白

先剖析下面代码

new Promise((resolve, reject) => {
    console.log('promise1');
    resolve();
})
  • 第一步console.log('promise1'),这是第一个promise实例
  • 第二步resolve(),他是一个异步,放入异步行列中,取名异步1
  • 第三步this.status 状况是pending

接着实行下面代码

.then(() => {
    console.log('then11');
    new Promise((resolve, reject) => {
        console.log('promise2');
        resolve();
    }).then(() => {
        console.log('then21');
    }).then(() => {
        console.log('then23');
    });
})
  • 由于状况是pending,将then要领回调函数到场实行行列(一个数组)守候实行(专用来放then要领的数组),该then要领取名要领1

重点接着实行什么?

并非实行.then(() => {console.log(then12)}),要记着的是then的参数要领实行机遇是当前(属于本身的)promise状况转变才会实行,谁转变resolve或许rejectd的实行,那末这里then的promise哪里来,就是上面的要领1中来看他的return值

所以最先实行异步1(我都有取名的,看👆),第一个promise实例状况变成FULFILLED

  • 起首resolve()参数为undefind不是一个promise范例,所以实行实行行列(一个数组),即要领1,也就是第一个then`的参数
  • 由于状况转变所以最先实行要领1
() => {
    console.log('then11');
    new Promise((resolve, reject) => {
        console.log('promise2');
        resolve();   //新的resolve 取名异步2
    }).then(() => { 
        console.log('then21');
    }).then(() => {
        console.log('then23');
    });
}
  • 第一步打印console.log('then11');
  • 又新建了一个Promise,打印console.log('promise2');
  • resolve();又一个异步,放入异步行列中,取名异步2
  • 然后由于新的promise它的状况是pengding,所以() => {console.log('then21');}要领放入新的promise的实行行列的数组中(和上面一样专用来放then要领的数组)
  • 同理背面的then并不回实行,它须要守候新的resolve的实行,来转变状况实行then

重点2

  • 由于要领1的没有return,即return 一个undefined,但我们都晓得then会默许返回一个return new Promise((resolve, reject) => {})对象,所以这时候他是实行了的一个异步操纵resolve()取名异步3,
  • 所以有了这个异步3,这个returnpromise的状况为pending,所以then(() => {console.log(then12)})到场到(专用来放then要领的数组)的实行回调数组中

然后最先实行异步行列的函数,有两个异步2和异步3,先实行异步2,接下来的操纵和重点2是一样的又会return new Promise((resolve, reject) => {}) ,又会有一个异步4resolve(),接着讲then要领放入数组中,守候resolve()转变promise状况来实行then要领

  • 所以在守候时期会实行异步3,然后打印console.log(then12)
  • 末了打印console.log(then23)

总结要点

  • then(func)实行机遇是守候一个与它相干的promise的状况转变
  • then(func)中的func默许会return new Promise((resolve, reject) => {resolve()})用于下一个then(func)
  • 假如我们手动return 一个promise效果就会差别,看下面例子

再变个名堂

new Promise((resolve, reject) => {
    console.log('promise1');
    resolve();      //异步1
}).then(() => {
    console.log('then11');
    return new Promise((resolve, reject) => {
        console.log('promise2');
        resolve();  //异步2  
    }).then(() => {
        
        console.log('then21');
        //默许resolve()  异步3
    }).then(() => {
        console.log('then23');
        //默许resolve()  异步4
    });
}).then(() => {
    console.log('then12');
});

剖析

  • 看到一个then(func)中我们直接返回了一个promise,所以先到场第一异步2,而且要守候它相干的promise状况转变,然则它状况转变了,那就是等异步2的实行,一旦实行,接着就是() =>{console.log('then23'); //默许resolve() 异步4}的实行了,所以异步4先一步比异步5到场,也就先实行了,
  • 所以效果就是
promise1
then11
promise2
then21
then23
then12

我再来变个样

new Promise((resolve, reject) => {
    console.log('promise1');
    resolve();  //异步1
}).then(() => {
    console.log('then11');
    new Promise((resolve, reject) => {
        console.log('promise2');
        resolve();  //异步2
    }).then(() => {
        console.log('then21'); 
        //异步3
    }).then(() => {
        console.log('then23');
        //异步4
    });
    return Promise.resolve(1)  //异步5
}).then(() => {
    console.log('then12');
});

剖析一下这几个异步就要能晓得答案了

  • console.log('promise1');
  • 先到场异步1, 实行后输出console.log('then11'); console.log('promise2');
  • 在到场异步2, 再到场异步5
  • 先实行异步2, console.log('then21'); 并将到场异步4
  • 再实行异步5, 但这个异步和下面的then不相干,由于这边隐蔽的会再下到场一个resolve()(即异步6)
  • 接着先实行异步4, 输出console.log('then23');
  • 接着先实行异步6, 输出console.log('then12');
    原文作者:Infinity
    原文地址: https://segmentfault.com/a/1190000019212964
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞