javascript 事件循环会在每次宏任务执行完毕后,立即清空微任务队列。具体做法是:引擎在调用栈为空时检查微任务队列,只要队列不为空,就持续取出队首任务并压入调用栈执行,直到微任务队列为空或达到最大递归深度限制,然后才渲染页面并进入下一个宏任务。

微任务与宏任务的执行顺序差异
Promise.then 回调属于微任务,而 setTimeout 属于宏任务。当两者在同一轮事件循环中被调度时,Promise 的回调会先于 setTimeout 的回调执行。这是因为 Promise 状态改变后会将回调加入微任务队列,而 setTimeout 将回调加入宏任务队列,引擎优先处理微任务。

console.log('1');
setTimeout(() => {
console.log('2');
}, 0);
Promise.resolve().then(() => {
console.log('3');
});
console.log('4');
预期输出:
1
4
3
2
微任务清空过程中的异常处理
如果在清空微任务队列的过程中某个任务抛出异常,引擎会停止继续执行后续的微任务,并将该异常传递给全局错误处理器(如 window.onerror 或 process.on('uncaughtException')),但不会中断当前宏任务的后续流程。这意味着未执行的微任务会被丢弃,而宏任务中的代码仍会继续运行。

console.log('Start');
setTimeout(() => {
console.log('Timeout');
}, 0);
Promise.resolve()
.then(() => {
console.log('Promise 1');
throw new Error('Error in Promise 1');
})
.catch((err) => {
console.log('Caught:', err.message);
});
console.log('End');
预期输出:
Start
End
Promise 1
Caught: Error in Promise 1
Timeout
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











