深入理解JavaScript事件循环(Event Loop):从宏任务到微任务
📅 2026/7/2 14:38:48
👁️ 阅读次数
📝 编程学习
很多前端开发者在面试或实际开发中,都会被JavaScript的“异步执行机制”绕晕。为什么setTimeout里的代码总是比Promise晚执行?今天,我们不背八股文,用最通俗的语言把事件循环(Event Loop)彻底讲透。
1. 为什么需要事件循环?
首先要明确一个核心概念:JavaScript是一门单线程语言。这意味着同一时间只能做一件事。如果我们在主线程上执行一个耗时3秒的网络请求,整个页面就会卡死3秒。为了解决这个问题,浏览器引入了事件循环机制,将耗时操作交给Web APIs处理,主线程则继续执行后续代码。
2. 宏任务与微任务的“插队”游戏
事件循环的核心,在于区分两种任务队列:
- 宏任务(MacroTask):包括整体代码块、
setTimeout、setInterval、I/O操作等。 - 微任务(MicroTask):包括
Promise.then、MutationObserver、queueMicrotask等。
它们的执行优先级是:微任务 > 宏任务。
3. 一次完整的事件循环流程
让我们来看一个经典的执行顺序:
- 主线程执行同步代码(第一个宏任务)。
- 遇到微任务(如
Promise.then),将其放入微任务队列。 - 遇到宏任务(如
setTimeout),将其放入宏任务队列。 - 同步代码执行完毕后,主线程立即清空当前所有的微任务队列。
- 微任务清空后,渲染引擎可能进行页面渲染。
- 从宏任务队列中取出一个任务执行,然后再次回到第4步。
4. 总结与避坑指南
理解了上述机制,我们就能明白:Promise的回调之所以优先于setTimeout,是因为它属于微任务,会在当前宏任务结束后、下一个宏任务开始前被“插队”执行。
在实际开发中,我们要尽量避免在微任务中执行极其耗时的同步操作,否则会导致页面渲染被无限期推迟,造成严重的卡顿。希望这篇文章能帮你彻底打通异步编程的任督二脉!如果觉得有用,别忘了点赞收藏,我们下期再见。
编程学习
技术分享
实战经验