html5

嵌套promise的执行顺序

2020-03-05  本文已影响0人  前端小旋风

先上代码
这是一段面试中总会遇见的题目

    new Promise(resolve => {
        console.log('1');
        resolve();
    }).then(() => {
        console.log('2');
        new Promise(resolve => {
            console.log('3');
            resolve();
        }).then(() => {
            console.log('4');
        }).then(() => {
            console.log('5');
        })
    }).then(() => {
        console.log('6');
        new Promise(resolve => {
            console.log('7');
            resolve();
        }).then(() => {
            console.log('8');
        }).then(() => {
            console.log('9');
        })
    })

好多次都死在这种烂题目上了
甚至曾经有一次面试
年轻的我告诉面试官,谁写出来这种代码我就弄死他


好了~
想解决这个问题首先在脑袋中想象一个长10十厘米,宽3厘米,高100厘米的长方体容器
这个容器的名字叫做执行栈
ok~
这一段代码首先进入执行栈中,并开始执行,我们把这一段代码命名为任务1
它的执行结果是打印了1到控制台

new Promise(resolve => {
      console.log('1');
        resolve();
    })

任务1输出的同时改变了promise的状态,所以promise后面的第一个.then可以执行了,promise属于微任务,所以放到执行栈的末尾来执行,命名为任务2
微任务:Promise、process.nextTick,微任务追加在本轮事件循环的末尾


then(() => {
        console.log('2');
        new Promise(resolve => {
            console.log('3');
            resolve();
        }).then(() => {
            console.log('4');
        }).then(() => {
            console.log('5');
        })
    })

任务1执行结束后,执行栈并没有任务执行,所以开始执行末尾的任务2
输出2到控制台,任务2总得promise会继续执行,紧接着输出3,resolve改变了promise的状态,所以任务2中的第一个then可以执行了,它被放到执行栈的末尾命名为任务3

then(() => {
            console.log('4');
        })

任务2执行结束后,会给最外层promise的第二个then返回一个promise所以第二个then也可以执行了,放到执行栈末尾命名为任务4

then(() => {
        console.log('6');
        new Promise(resolve => {
            console.log('7');
            resolve();
        }).then(() => {
            console.log('8');
        }).then(() => {
            console.log('9');
        })
    })

此时执行栈没有任务执行就会继续执行任务3
输出4同时任务2中的第二个then被触发,放入执行栈底部,命名为任务5

then(() => {
            console.log('5');
        })

继续执行任务4
输出6 7
执行 resolve 任务4中的第一个then被触发,放入执行栈底部,命名为任务6

then(() => {
            console.log('8');
        })

继续执行任务5
输出 5


继续执行任务6
输出8
任务4中的第二个then因为第一个then的执行也被触发
进入执行栈命名为任务7

then(() => {
            console.log('9');
        })

继续执行任务7
输出9


至此所有代码运行完毕
输出结果
1 2 3 4 6 7 5 8 9

锵锵锵~
会了么


此致
敬礼~
小旋风

我建了一个前端微信交流群,欢迎大家加入,qq中转群号:1076484243

上一篇 下一篇

猜你喜欢

热点阅读