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)
解析:
-
调用
first函数:first函数返回一个新的Promise对象,并且立即执行Promise的回调函数。
-
执行外部
Promise的回调函数:console.log(3):立即执行,打印3。- 继续执行到
let p = new Promise((resolve, reject) => {...})。
-
执行内部
Promise的回调函数:console.log(7):立即执行,打印7。- 设置
setTimeout,回调会在事件队列中等待。 resolve(1):内部Promise被解决为1。
-
执行
p.then:- 内部
Promise被解决,p.then回调被加入微任务队列。
- 内部
-
外部
Promise继续执行:resolve(2):外部Promise被解决为2。
-
first().then:- 外部
Promise的解决会将first().then的回调加入微任务队列。
- 外部
-
执行同步代码
console.log(4):- 在当前事件循环的最后一个同步任务,打印
4。
- 在当前事件循环的最后一个同步任务,打印
-
执行微任务队列:
-
先执行
p.then的回调。console.log(1):打印1,因为内部Promise已经解决为1。
-
再执行
first().then的回调。console.log(2):打印2,因为外部Promise已经解决为2。
-
-
执行事件队列中的
setTimeout回调:- 最后执行
setTimeout回调函数。 console.log(5):打印5。
- 最后执行
正确的打印顺序
按照上述分析,代码的打印顺序应该是:
3- 外部Promise开始执行。7- 内部Promise开始执行。4- 外部Promise创建完成后立即打印。1- 内部Promise的then回调。2- 外部Promise的then回调。5-setTimeout回调。
所以,最终输出的顺序是:3, 7, 4, 1, 2, 5。