北京市网站建设_网站建设公司_Windows Server_seo优化
2025/12/29 18:51:57 网站建设 项目流程

彻底搞懂 JavaScript 事件循环:宏任务、微任务与同步代码的关系

“JavaScript 是单线程的,那它是如何处理异步操作的?”
答案就是:事件循环(Event Loop)

很多前端开发者对setTimeoutPromise的执行顺序感到困惑,其实只要理解了事件循环的核心机制,一切都会豁然开朗。本文将用最直白的语言,带你彻底掌握 JavaScript 的事件循环。


一、为什么需要事件循环?

JavaScript 是单线程语言——同一时间只能做一件事。
但现实开发中,我们经常要处理网络请求、定时器、用户交互等耗时操作。如果这些操作阻塞主线程,页面就会“卡死”。

为了解决这个问题,JavaScript 引入了异步机制,而事件循环就是协调同步与异步任务的调度器。


二、事件循环的核心组成

事件循环依赖三个关键部分:

组件作用
调用栈(Call Stack)记录当前正在执行的函数
宏任务队列(Macro Task Queue)存放宏任务,如setTimeoutsetInterval、I/O、UI 渲染等
微任务队列(Microtask Queue)存放微任务,如Promise.thenqueueMicrotaskMutationObserver

⚠️ 注意:微任务的优先级高于宏任务


三、宏任务 vs 微任务

常见宏任务(Macro Task):

  • script(整个 JS 脚本)
  • setTimeout/setInterval
  • setImmediate(Node.js)
  • I/O 操作
  • UI 渲染(浏览器)

常见微任务(Microtask):

  • Promise.then/.catch/.finally
  • queueMicrotask()
  • MutationObserver(浏览器)
  • process.nextTick()(Node.js,优先级甚至高于 Promise)

四、关键原则:执行顺序

每执行完一个宏任务,就立刻清空当前所有的微任务,然后再取下一个宏任务。

可以用这个流程图来记忆:

[宏任务1] → 执行同步代码 → 注册微任务 & 宏任务 → 宏任务1结束 → [清空所有微任务] → [宏任务2] → [清空所有微任务] → ...

五、经典例子解析

来看这段几乎面试必考的代码:

console.log('1');setTimeout(()=>{console.log('2');},0);Promise.resolve().then(()=>{console.log('3');});console.log('4');

执行过程分解:

  1. 第一个宏任务(全局脚本)开始执行

    • 输出'1'
    • setTimeout→ 注册一个宏任务(放入宏任务队列)
    • Promise.then→ 注册一个微任务(放入微任务队列)
    • 输出'4'
    • ✅ 当前宏任务执行完毕
  2. 清空微任务队列

    • 执行Promise.then→ 输出'3'
  3. 进入下一轮事件循环,执行下一个宏任务

    • 执行setTimeout回调 → 输出'2'

最终输出:

1 4 3 2

六、重要结论

同步代码本身就是宏任务
整个<script>标签中的顶层代码,就是事件循环中的第一个宏任务

微任务总是在当前宏任务结束后立即执行
不是“所有宏任务跑完再跑微任务”,而是“每个宏任务后都清空微任务队列”。

宏任务之间会被微任务“插队”
这就是为什么Promise.then总是比setTimeout先执行(即使延时为 0)。


七、常见误区澄清

误区1setTimeout(fn, 0)会“立刻”执行
→ 实际上它只是尽快安排一个宏任务,仍需等待当前宏任务和所有微任务完成。

误区2:微任务和宏任务是并行的
→ 它们都在同一个线程中,按事件循环规则串行执行

误区3Promise是异步的,所以和setTimeout一样
→ 错!Promise.then微任务,优先级远高于setTimeout这类宏任务。


八、延伸:Node.js 的差异(可选了解)

在 Node.js 中,事件循环分为多个阶段(timers、poll、check 等),且process.nextTick优先级高于Promise
但在现代 Node.js(v11+)中,浏览器与 Node 的行为已基本对齐,日常开发可按统一模型理解。


九、总结

JavaScript 的事件循环 = 宏任务 + 微任务 + 调度规则

记住一句话:

“同步代码是一个宏任务;每执行完一个宏任务,就立刻清空所有微任务。”

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询