02 宏任务与微任务
![[Screenshot 2026-03-16 at 1.06.10 PM.png]] ![[Screenshot 2026-03-16 at 1.56.00 PM.png]]
宏任务(Macro Task)¶
指那些由浏览器或Node.js环境提供的、在主线程上执行的任务。它们通常与用户交互或I/O操作相关。包括:
- setTimeout()
- setInterval()
- setImmediate()(只有 Node.js 有)
- 用户事件(点击、键盘输入)
- 网络请求的回调(Ajax、fetch 的底层)
特点: - 宏任务的执行通常需要一定的时间,它们会占用主线程,直到任务完成。 - 宏任务的回调函数在事件循环的每个阶段结束时被执行。
示例:
在这个例子中,setTimeout是一个宏任务。尽管setTimeout的延迟时间为0,它的回调函数也会在当前执行栈清空后,微任务队列处理完毕后执行。
执行流程: 1. JS 引擎直接执行,输出Start 2. 遇到setTimeout(...),JS 引擎不会自己计时。它会把这个任务交给浏览器,浏览器 Web API 开始计时1000ms 3. JS 引擎直接执行,输出End 4. 1 秒后,浏览器说时间到了,于是浏览器把这个函数() => console.log("B")放进 任务队列。 5. Event Loop 发现主线程空了,于是把任务放回 JS 引擎执行,输出Timeout
微任务(Micro Task)¶
微任务是指那些在当前执行栈执行完毕后立即执行的任务。它们通常用于处理一些小的、快速的任务。包括:
- Promise.then / .catch / .finally
- async / await(await 后面的代码)
- queueMicrotask()
- MutationObserver(监听 DOM 变化,面试不常考)
特点:
- 微任务的执行速度通常比宏任务快,因为它们在当前执行栈清空后立即执行,不需要等待事件循环的下一个阶段。
- 微任务的回调函数在当前执行栈清空和事件队列处理完毕后立即执行。
示例:
console.log('Start');
Promise.resolve().then(function() {
console.log('Promise');
});
console.log('End');
在这个例子中,Promise的.then()回调是一个微任务。它的回调函数会在当前执行栈清空后立即执行,因此'Promise'会在'End'之后输出。
这些 API 是哪里来的?¶
这些函数不是 JS 语言本身的。JS 语言本身只有:变量、函数、循环、对象、数组这些。setTimeout、fetch、document 这些,是浏览器送给你的礼物,叫做 Web API。
浏览器是一个大系统,有以下部分: - JS Engine(V8):负责执行JS代码,只会:计算、函数调用、变量处理 - Web APIs:包括setTimeout fetch DOM事件 click addEventListener - Callback Queue(任务队列):浏览器完成任务后,会把回调函数放到这里。 - Event Loop:负责把队列里的任务放回 JS 执行。