浏览器中针对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的回调。依次类推就出现了上面的打印结果

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
JavaScript,setInterval和Promise执行顺序是根据事件循环机制来确定的。事件循环是JavaScript用来处理异步操作的一种机制。首先,让我们来了解一下事件循环的基本原理。 JavaScript是单线程执行的,意味着同时只能执行一段代码。当某一段代码正在执行时,其他任务必须等待。这种执行方式也被称为"阻塞式执行"。JavaScript的任务队列用于存储等待执行的任务。一旦当前任务执行毕,事件循环会从任务队列取出下一个任务并执行。 对于setInterval和Promise执行顺序问题,具体的执行顺序取决于它们被添加到任务队列的时间和优先级。根据引用的说明,事件循环的优先级从高到低依次是:主代码块 > setImmediate > MessageChannel > setTimeout / setInterval。 如果存在多个setInterval和Promise任务,它们会根据优先级和添加到任务队列的顺序依次执行。setInterval的任务会按照指定的时间间隔重复执行,而Promise的任务则会在其他任务执行毕后被执行。 需要注意的是,Promise的then方法是异步执行的,它会在当前任务执行毕后被添加到任务队列,等待执行。因此,即使是在Promise的then方法使用了setTimeout,它也会按照任务队列的顺序被执行。具体的执行顺序可能因为任务队列的任务数量和优先级而有所不同。 综上所述,setInterval和Promise执行顺序是根据它们被添加到任务队列的时间和优先级来确定的。具体的执行顺序可以通过事件循环机制来理解。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [js 关于setTimeout和Promise执行顺序问题](https://blog.csdn.net/zlzbt/article/details/100577954)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* *3* [JavaScript--Promise执行顺序](https://blog.csdn.net/qq_45633813/article/details/126781947)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值