不清晰的题:
第一题:
console.log(1);
new Promise(resolve => {
resolve();
console.log(2)
}).then(() => {
console.log(3);
});
setTimeout(() => {
console.log(4)
}, 0);
console.log(5)
结果是: 1 2 5 3 4
注意点:
详细原因分析:
第一步:同步代码立即执行
console.log(1) 直接输出 1
执行 new Promise(executor),executor 函数是同步执行的,因此:
resolve() 将 Promise 状态改为 fulfilled,并安排微任务(then 回调)
console.log(2) 输出 2
setTimeout(... , 0) 将回调加入宏任务队列(注意是 0 延时,但不是立即执行)
console.log(5) 输出 5
此时输出:1 2 5
调用栈清空,开始执行微任务。
第二步:微任务队列
之前 Promise 的 resolve() 触发了 then 回调,回调函数 () => { console.log(3) } 被加入微任务队列
当前调用栈清空后,事件循环先检查微任务队列并执行:
输出 3
第三步:宏任务队列
微任务队列清空后,事件循环进入下一个循环,检查宏任务队列
setTimeout 的回调 () => { console.log(4) } 执行
输出 4
第二题:
const promise = new Promise((resolve, reject) => {
console.log(1);
console.log(2);
});
promise.then(() => {
console.log(3);
});
console.log(4);
输出1 2 4 没有3 因为没有resolve
第三题:
const promise = new Promise((resolve, reject) => {
console.log(1);
setTimeout(() => {
console.log("timerStart");
resolve("success");
console.log("timerEnd");
}, 0);
console.log(2);
});
promise.then((res) => {
console.log(res);
});
console.log(4);
1 2 4 timerstart timeend success
注意点:resolve的时候状态变化,以及放入微任务队列,等宏任务结束执行后,立即执行宏任务。
第四题:
Promise.resolve().then(() => {
console.log('promise1');
const timer2 = setTimeout(() => {
console.log('timer2')
}, 0)
});
const timer1 = setTimeout(() => {
console.log('timer1')
Promise.resolve().then(() => {
console.log('promise2')
})
}, 0)
console.log('start');
打印顺序: start promise1 timer1promise2 timer2
为什么是这个顺序?
微任务优先于宏任务:即使 setTimeout 延时为 0,也要等当前所有微任务执行完。
任务队列顺序:宏任务按加入顺序执行,timer1 比 timer2 先加入队列,所以先执行。
微任务在宏任务之间执行:当执行一个宏任务时,如果产生了新的微任务,会在当前宏任务结束后、下一个宏任务前立即执行。
第五题: 值穿透
Promise.resolve(1)
.then(2)
.then(Promise.resolve(3))
.then(console.log)
打印1
逐行分析
Promise.resolve(1)
创建一个状态为 fulfilled、值为 1 的 Promise。
.then(2)
2 不是函数,发生值穿透。
→ 忽略这个 .then(),Promise 的值保持为 1,继续传递。
.then(Promise.resolve(3))
Promise.resolve(3) 是一个 Promise 对象,不是一个函数,所以仍然发生值穿透。
注意:即使 Promise.resolve(3) 是一个 Promise,但作为参数时它是对象而不是函数,所以不会执行。
→ 忽略这个 .then(),Promise 的值仍为 1。
.then(console.log)
console.log 是一个函数,所以会执行。
此时接收到前一个 Promise 传递的值 1,执行 console.log(1)。
打印题关注promise对象

打印题.png