同步任务 --> 微任务 --> 宏任务
再考虑下面这个较有代表性的稍微复杂点的嵌套情况(答案在代码最右侧,先思考再检查):
console.log(0);
setTimeout(() => {
console.log(1);
}, 1000);
setTimeout(() => {
console.log(2);
}, 0);
new Promise(resolve => {
console.log(3);
setTimeout(() => {
console.log(4);
}, 500);
resolve(5);
}).then(res => {
setTimeout(() => {
console.log(6);
}, 0)
console.log(res);
}) // 0
setTimeout(() => { // 9
console.log(7); // 5
}, 200) // 2
setTimeout(() => { // 8
console.log(8); // 6
}, 0) // 7
console.log(9); // 1
查看答案后看看结果和预想的是否一致;可能唯一有疑惑的地方就是 3 和 9 的输出顺序,因为前面不是讲同步任务会先于 Promise 微任务执行吗?应该是 9 在 3 前面才对呀?其实不然,并不是在 Promise 函数代码内的都是微任务,因为所谓 微任务 就是一项任务,即指令下达后要做的事情,那么在函数中 要做的事 其实是 .then()
中包裹的代码,而 Promise 函数中包裹的代码(输出 3、4、5)算作 同步任务 的一部分,所以 3 会先于 9 输出;
另外,我们还能注意到,输出 6 的代码被 setTimeout
这个宏任务包裹,但这个宏任务又被 .then()
这个微任务包裹,根据最终的结果,这个宏任务基本还是被正常对待,只是在相同延时的宏任务中被最后执行了,尽管在代码中这个微任务中的宏任务写在了普通宏任务的前面,所以最终 8 会比 6 先输出;