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
    评论
回答: Promise执行顺序可以总结如下:首先,Promise对象会立即执行,即使没有设置回调函数。其次,Promise对象的状态会根据异步操作的结果进行改变。当异步操作成功完成时,Promise的状态会变为fulfilled;当异步操作失败时,Promise的状态会变为rejected。接下来,根据Promise对象的状态,会执行相应的回调函数。如果Promise对象的状态为fulfilled,会执行then方法中的回调函数;如果Promise对象的状态为rejected,会执行catch方法中的回调函数。需要注意的是,catch方法只捕获最近的then的回调函数,前面的then的执行不成功结果会被后面的reject回调函数执行,如果没有后续then回调函数执行,则会被catch捕获执行。总之,Promise执行顺序是根据异步操作的结果来决定状态的改变,并根据状态执行相应的回调函数。\[1\]\[2\] #### 引用[.reference_title] - *1* *3* [Promise 实现原理](https://blog.csdn.net/shi851051279/article/details/113922007)[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^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [【异步系列二】Promise原理及执行顺序详解](https://blog.csdn.net/qq_41131745/article/details/126974598)[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^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值