温故知新(六九)const p1 = () => (new Promise((resolve, reject) => { console.log(1); let p2 = new Pr

写出输出结果:

const p1 = () => (new Promise((resolve, reject) => {
    console.log(1);
    let p2 = new Promise((resolve, reject) => {
        console.log(2);
        const timeOut1 = setTimeout(() => {
            console.log(3);
            resolve(4);
        }, 0)
        resolve(5);
    });
    resolve(6);
    p2.then((arg) => {
        console.log(arg);
    });

}));
const timeOut2 = setTimeout(() => {
    console.log(8);
    const p3 = new Promise(reject => {
        reject(9);
    }).then(res => {
        console.log(res)
    })
}, 0)


p1().then((arg) => {
    console.log(arg);
});
console.log(10);

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

答案:

1
2
10
5
6
8
9
3

第一步:浏览器开始将 script 标签包裹的所有代码看作宏任务执行,发现有普通的函数 p1,宏任务 timeOut2,使其进入宏任务队列,微任务 p1.then 进入微任务队列,普通的函数 p1 入栈,输出 1,普通函数 p2 入栈输出 2,有宏任务 timeOut1 入列,微任务 p2.then 入列。
第二步:宏任务执行完之后找微任务,队列是先进先出,then 按照 resolve 处理顺序,先执行的是 p2 中的 resovle 所以执行 p2.then,输出 5,再执行 p1 的 resolve,执行 p1.then,输出 6
第三步:微任务执行完后执行宏任务,由于两个 timeout 等待时间一样,按照队列顺序先执行 timeOut2 ,输出 8,p3.then 微任务入列,宏任务执行完毕后执行微任务 p3.then 输出 9。
第四步:执行 tineOut1,输出 3,由于 p2 的 promise 对象以及被执行过所以 4 不再执行

为了理解第二步为什么 p2.then 先于 p1.then 先执行,我们可以在打印上多加一点内容

var p1 = () => (new Promise((resolve, reject) => {
    console.log(1);
    let p2 = new Promise((resolve, reject) => {
        console.log(2);
        var timeOut1 = setTimeout(() => {
            console.log(3);
        }, 0)
        resolve('5,resolve2');
    });
    resolve('6,resolve1');
    p2.then((arg) => {
        console.log(arg,'p2.then');
    });

}));
var timeOut2 = setTimeout(() => {
    console.log(8);
    var p3 = new Promise(reject => {
        reject(9);
    }).then(res => {
        console.log(res)
    })
}, 0)


p1().then((arg) => {
    console.log(arg,'p1.then');
});
console.log(10);

结果:

1
2
10
5,resolve2 p2.then
6,resolve1 p1.then
8
9
3

扩展:

如果两个timeout等待时间不一致结果也就不同了:

const p1 = () => (new Promise((resolve, reject) => {
 console.log(1);
 let p2 = new Promise((resolve, reject) => {
  console.log(2);
  const timeOut1 = setTimeout(() => {
   console.log(3);
   resolve(4);
  }, 0)
  resolve(5);
 });
 resolve(6);
 p2.then((arg) => {
  console.log(arg);
 });

}));
const timeOut2 = setTimeout(() => {
 console.log(8);
 const p3 = new Promise(reject => {
  reject(9);
 }).then(res => {
  console.log(res)
 })
}, 1000)


p1().then((arg) => {
 console.log(arg);
});
console.log(10);

结果:

1
2
10
5
6
3
8
9

第一步:浏览器开始将 script 标签包裹的所有代码看作宏任务执行,发现有普通的函数 p1,宏任务 timeOut2,使其进入宏任务队列,微任务 p1.then 进入微任务队列,普通的函数 p1 入栈,输出 1,普通函数 p2 入栈输出 2,有宏任务 timeOut1 入列,微任务 p2.then 入列。
第二步:宏任务执行完之后找微任务,队列是先进先出,then 按照 resolve 来定,先执行的是 p2 中的 resovle所以执行 p2.then,输出 5,再执行 p1的resolve,执行 p1.then,输出 6
第三步:微任务执行完后执行宏任务,由于 timeOut1 等待时间短,所以先执行,输出 3,由于 p2 的 promise 对象以及被执行过所以 4 不再执行;再执行 timeOut2 ,输出 8,p3.then 微任务入列
第四步:宏任务执行完毕后执行微任务 p3.then 输出 9

 

 

  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值