Promise执行顺序详解

某大厂的一道普通的面试题(稍作修改,增加了难度),可以先看看题目,然后再对照下答案。

const p = () => new Promise((resolve, reject) => {
  console.log(1)

  const q = () => new Promise((resolve, reject) => {
    console.log(3)
    resolve(4)
  })

  const r = () => new Promise((resolve, reject) => {
    console.log(7)
    resolve(8)
  })

  setTimeout(() => {
    console.log(10)
  }, 0);

  resolve(2)

  q().then(res => {
    console.log(res)
    setTimeout(() => {
      console.log(6)
    }, 0);
  })

  r().then(res => {
    console.log(res)
    setTimeout(() => {
      console.log(9)
    }, 0);
  })
})

p().then(res => {
  console.log(res)
})

console.log(5)
/**
 * 
 * Promise是一种异步编程的解决方案,主要解决的是回调函数多层嵌套造成的回调地狱的问题
 * Promise对象的内部有三种状态,pending fullfilled rejected, pendeing是最初始的状态,成功是resolve(res),失败是reject(res),成功或者失败的结果均作为参数被抛出,并分别在then和catch中作为参数暴露
 * Promise 一旦被声明就会立即执行,此时内部的代码会按照顺序执行,但是resolve(res)的代码会是异步,所以当Promise()中的同步代码会先执行,resolve()的代码会后执行,resolve()之后的也先执行,Promise中的所有的同步和异步代码执行完毕之后resolve()才执行
 * 1 3 7 5 4 8 2 10 6 9
 * 下面这段代码的执行顺序如上所示
 * 我们应该分三个阶段去看这段代码的执行
 * 阶段1: 同步代码先执行
 * 因为同步代码最先执行,又因为Promise一旦被调用就会立即执行所以会打印 - 1 
 * resolve(2) 作为异步仍在等待同步代码执行完毕且 p 内部的全部代码执行完毕之后才会被执行
 * 然后声明了一个q, r 的 Promise 然后调用 q ,同步代码立即执行 打印 - 3
 * resolve(4) 作为异步仍在等待同步代码执行完毕且 q 内部的代码全部执行完成之后才会被执行
 * 同理,打印 r 中的同步代码 - 7 ,resolve(8)作为异步等待
 * 到这里 p 内部的同步代码执行完毕了,此时跳出 p 执行外部的同步代码,打印 - 5
 * 
 * 此时执行的代码的顺序为 1 3 7 5
 * 
 * 阶段2:Promise()中异步的resolve()执行
 * 当同步执行之后就是resolve()异步的代码,p()先执行,但是 p()自己的resolve() 必须等到其内部全部的异步resove()执行完毕之后才能够执行
 * 所以此时应该是先执行的是 q().then() 打印 - 4
 * 然后打印的是 r().then() 打印 - 8 
 * 然后 p() 内部的 resolve() 异步全部执行完毕,最后就要执行 p().then() 打印2
 * 
 * 此时执行的代码的顺序为 4 8 2
 * 
 * 阶段3:setTimeout 异步函数的执行
 * 由于 Promise 是 JS 引擎的内部任务,而setTimeout 是浏览器外部的API 所以 Promise 的优先级高于 setTimeout ,也就是因此,只有所有的 Promise()内的resolve()执行完成之后才会执行 setTimeout 函数
 * 而 setTimeout 函数执行的顺序就看它被调用的先后顺序了
 * 从上到下依次调用 打印 - 10 6 9
 * 
 * 到此三个阶段全部结束 程序执行完毕
 */
  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值