浏览器中针对Promise所引发的执行顺序问题

浏览器中针对Promise所引发的执行顺序问题


首先,在阅读本章前,请确认你已经掌握了基本的Promise的用法

我们先来看一个简单的例子

   new Promise((resolve, reject) => {
      resolve()
    }).then((value) => {
      console.log('Promise 1')
    })

    console.log('log 1')
    /*
    执行结果:
    log 1
    Promise 1
    */

为什么会先执行console.log('log 1')?如果你了解过浏览器的事件循环机制,你会知道,这是因为Promise实例的.then里的回调并不会立即执行,而会被添加到异步队列等待执行

接下来我们再来添加一点代码:

    new Promise((resolve, reject) => {
      resolve()
    }).then((value) => {
      console.log('Promise 1')
    })

    new Promise((resolve, reject) => {
      resolve()
    }).then((value) => {
      console.log('Promise 2')
    })

    console.log('log 1')
    /*
    执行结果:
    log 1
    Promise 1
    Promise 2
    */

同样的原因,两个Promise实例的.then里的回调函数被依次添加到了异步队列,根据先进先出的原则,所以会先打印Promise 1然后是Promise 2

接下来,我们利用Promise的链式调用,再来添加一些代码

    new Promise((resolve, reject) => {
      resolve()
    })
      .then((value) => {
        console.log('Promise 1')
        return Promise.resolve()
      })
      .then(() => {
        console.log('Promise 3')
      })

    new Promise((resolve, reject) => {
      resolve()
    })
      .then((value) => {
        console.log('Promise 2')
        return Promise.resolve()
      })
      .then(() => {
        console.log('Promise 4')
      })

    console.log('log 1')
     /*
    执行结果:
    log 1
    Promise 1
    Promise 2
    Promise 3
    Promise 4
    */

这看起来好像并不难,他的执行顺序似乎在我们预料之中,但我发现,通过他的执行顺序,又引发了一个新的思考,我们可以改写一下这个代码,使他们等价:

    let p1 = new Promise((resolve, reject) => {
      resolve()
    })
    let p3 = p1.then((value) => {
      console.log('Promise 1')
      return Promise.resolve()
      // 等价于
      //return new Promise(resolve => resolve())
    })
    p3.then(() => {
      console.log('Promise 3')
    })
    console.log(p3)

    let p2 = new Promise((resolve, reject) => {
      resolve()
    })
    let p4 = p2.then((value) => {
      console.log('Promise 2')
      return Promise.resolve()
    })
    p4.then(() => {
      console.log('Promise 4')
    })

    console.log('log 1')

执行结果:
Promise {< pending>}
log 1
Promise 1
Promise 2
Promise 3
Promise 4

我们可以知道,p1一上来就被改变了状态,再向下执行p1.then里的回调会被添加进异步队列,并且会返回promise实例,p3就是这个promise实例,因为p1.then的回调并没有开始执行,通过打印可以看到他的状态为pending,所以执行到p3.then他的回调并不会被添加到异步队列,这时候异步队列仅有p1.then的回调,继续向下就像刚才一样,p2的回调被添加进异步队列,p4是一个状态为pending的promise实例,p4.then的回调并不会添加到异步队列。
等到异步队列开始执行,这时候只有两个需要执行的回调就是p1.then的回调和p2.then的回调,p1.then执行的时候将p3状态改为 fulfilled 然后p3.then的回调被添加进异步队列,这时异步队列p2.then的回调和p3.then的回调。依次类推就出现了上面的打印结果

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值