同步代码先执行,微任务优先于宏任务。JavaScript 通过事件循环协调任务:同步任务入栈执行;异步任务分微任务(如 Promise.then)和宏任务(如 setTimeout)进入对应队列;同步执行完后,先清空微任务队列,再取宏任务执行。例如 console.log('1')、setTimeout、Promise.then、console.log('4') 的输出顺序为 1 → 4 → 3 → 2,因 '1' 和 '4' 同步执行,Promise 回调为微任务,在本轮末尾执行,setTimeout 为宏任务延至下轮执行。事件循环持续检查调用栈,清空微任务后执行宏任务,如此反复。掌握此机制是理解 JS 异步关键。

JavaScript 是单线程语言,依靠事件循环(Event Loop)机制来协调代码的执行顺序,特别是在处理异步操作时。它决定了同步代码、异步回调、微任务和宏任务的执行优先级。
同步代码优先执行
JavaScript 会按代码书写顺序立即执行所有同步任务。这些任务运行在主线程上,形成调用栈,逐个完成。
例如:
console.log('A');
console.log('B');
输出顺序一定是 A → B,因为它们是同步代码,直接入栈执行。
异步任务进入任务队列
当遇到异步操作(如 setTimeout、setInterval、Promise.then、fetch 等),它们不会立即执行,而是被放入不同的任务队列中等待处理。
立即学习“Java免费学习笔记(深入)”;
事件循环持续检查调用栈是否为空。一旦空闲,就开始从队列中取出任务执行。
- 宏任务(Macrotask):包括 setTimeout、setInterval、I/O、UI 渲染等。
- 微任务(Microtask):包括 Promise.then/catch/finally、queueMicrotask、MutationObserver 等。
微任务优先于宏任务执行
每次同步代码执行完毕后,事件循环会先清空当前所有的微任务队列,再执行下一个宏任务。
看一个典型例子:
console.log('1');
setTimeout(() => {
console.log('2');
}, 0);
Promise.resolve().then(() => {
console.log('3');
});
console.log('4');
输出结果是:1 → 4 → 3 → 2
说明:
- '1' 和 '4' 是同步代码,最先输出。
- Promise 的 then 回调是微任务,在本轮事件循环末尾执行。
- setTimeout 是宏任务,要等到下一轮事件循环才执行。
事件循环的工作流程总结
整个执行流程可以概括为:
- 执行全局同步代码,产生执行栈。
- 异步任务被挂起,对应的回调进入相应队列(微任务或宏任务)。
- 同步代码执行完,调用栈清空。
- 立即执行所有当前可用的微任务。
- 取一个宏任务执行(如 setTimeout 回调),然后再次清空微任务队列。
- 重复以上过程。
基本上就这些。理解微任务先于宏任务执行,是掌握 JavaScript 异步行为的关键。不复杂但容易忽略。










