promise相关题目

44 阅读1分钟
const first = () =>
  new Promise((resolve, reject) => {
    console.log(3)
    let p = new Promise((resolve, reject) => {
      console.log(7)
      setTimeout(() => {
        console.log(5)
        resolve(6) //状态已经被外部的状态1改变,所以这里的状态不会被执行改变
      }, 0)
      resolve(1)
    })
    resolve(2)
    p.then(arg => {
      console.log(arg)
    })
  })
first().then(arg => {
  console.log(arg)
})
console.log(4)

解析:

  1. 调用 first 函数:

    • first 函数返回一个新的 Promise 对象,并且立即执行 Promise 的回调函数。
  2. 执行外部 Promise 的回调函数:

    • console.log(3):立即执行,打印 3
    • 继续执行到 let p = new Promise((resolve, reject) => {...})
  3. 执行内部 Promise 的回调函数:

    • console.log(7):立即执行,打印 7
    • 设置 setTimeout,回调会在事件队列中等待。
    • resolve(1):内部 Promise 被解决为 1
  4. 执行 p.then:

    • 内部 Promise 被解决,p.then 回调被加入微任务队列。
  5. 外部 Promise 继续执行:

    • resolve(2):外部 Promise 被解决为 2
  6. first().then:

    • 外部 Promise 的解决会将 first().then 的回调加入微任务队列。
  7. 执行同步代码 console.log(4) :

    • 在当前事件循环的最后一个同步任务,打印 4
  8. 执行微任务队列:

    • 先执行 p.then 的回调。

      • console.log(1):打印 1,因为内部 Promise 已经解决为 1
    • 再执行 first().then 的回调。

      • console.log(2):打印 2,因为外部 Promise 已经解决为 2
  9. 执行事件队列中的 setTimeout 回调:

    • 最后执行 setTimeout 回调函数。
    • console.log(5):打印 5

正确的打印顺序

按照上述分析,代码的打印顺序应该是:

  1. 3 - 外部 Promise 开始执行。
  2. 7 - 内部 Promise 开始执行。
  3. 4 - 外部 Promise 创建完成后立即打印。
  4. 1 - 内部 Promise 的 then 回调。
  5. 2 - 外部 Promise 的 then 回调。
  6. 5 - setTimeout 回调。

所以,最终输出的顺序是:3, 7, 4, 1, 2, 5