事件循环是JavaScript处理异步操作的核心机制,它的执行顺序直接决定了代码的运行结果。要理解事件循环的执行顺序,首先需要明确它的基本运行规则:先执行所有同步任务,再执行微任务队列中的所有任务,最后执行宏任务队列中的一个任务,之后重复这个流程。

基础执行顺序演示
下面的代码展示了同步任务、微任务、宏任务的基础执行顺序,我们可以通过输出结果直观看到执行流程。
// 同步任务
console.log('同步任务1');
// 微任务:Promise.then回调
Promise.resolve().then(() => {
console.log('微任务1');
});
// 宏任务:setTimeout回调
setTimeout(() => {
console.log('宏任务1');
}, 0);
// 同步任务
console.log('同步任务2');
运行上述代码,输出顺序为:同步任务1、同步任务2、微任务1、宏任务1。这符合事件循环的基础规则,同步任务优先执行,之后清空微任务队列,再执行一个宏任务。
嵌套微任务的执行顺序
当微任务中又产生新的微任务时,新的微任务会继续在当前微任务队列中执行,直到微任务队列清空才会执行宏任务。
console.log('同步任务开始');
Promise.resolve().then(() => {
console.log('第一个微任务');
// 微任务中再生成微任务
Promise.resolve().then(() => {
console.log('嵌套的微任务');
});
});
Promise.resolve().then(() => {
console.log('第二个微任务');
});
setTimeout(() => {
console.log('宏任务');
}, 0);
console.log('同步任务结束');
输出顺序为:同步任务开始、同步任务结束、第一个微任务、第二个微任务、嵌套的微任务、宏任务。可以看到嵌套的微任务会在当前微任务队列的其他微任务执行完之后,再继续执行,直到所有微任务都清空。
宏任务与微任务混合场景
当有多个宏任务和微任务混合时,每执行完一个宏任务,都会先检查并执行所有微任务,再执行下一个宏任务。
setTimeout(() => {
console.log('第一个宏任务');
Promise.resolve().then(() => {
console.log('第一个宏任务产生的微任务');
});
}, 0);
setTimeout(() => {
console.log('第二个宏任务');
Promise.resolve().then(() => {
console.log('第二个宏任务产生的微任务');
});
}, 0);
Promise.resolve().then(() => {
console.log('初始微任务');
});
输出顺序为:初始微任务、第一个宏任务、第一个宏任务产生的微任务、第二个宏任务、第二个宏任务产生的微任务。这是因为第一个宏任务执行完后,会先执行它产生的微任务,再执行第二个宏任务,第二个宏任务执行完后再执行它产生的微任务。
常见异步API的分类
为了更清晰地判断执行顺序,我们需要知道常见异步API属于微任务还是宏任务,下面是常见的分类:
| 任务类型 | 常见API |
|---|---|
| 微任务 | Promise.then/catch/finally、process.nextTick(Node环境)、queueMicrotask |
| 宏任务 | setTimeout、setInterval、setImmediate(Node环境)、requestAnimationFrame、I/O操作 |
掌握这些分类后,遇到复杂的异步代码时,我们可以按照先同步、再微任务、最后宏任务的顺序逐步分析,就能准确判断代码的执行顺序。
事件循环JavaScript异步编程执行顺序修改时间:2026-07-01 23:06:22