news 2026/4/16 13:03:17

面试题:了解事件循环吗

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
面试题:了解事件循环吗

彻底搞懂 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 的事件循环 = 宏任务 + 微任务 + 调度规则

记住一句话:

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

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/16 12:07:13

RoPE位置编码原理解析:在PyTorch-CUDA-v2.7中实现细节

RoPE位置编码原理解析&#xff1a;在PyTorch-CUDA-v2.7中实现细节 在大语言模型&#xff08;LLM&#xff09;飞速演进的今天&#xff0c;Transformer 架构早已成为自然语言处理领域的基石。然而&#xff0c;随着上下文长度不断扩展——从最初的512扩展到如今动辄32K甚至更长—…

作者头像 李华
网站建设 2026/4/16 9:20:36

大模型上下文扩展技术:PyTorch-CUDA-v2.7支持长序列处理

大模型上下文扩展技术&#xff1a;PyTorch-CUDA-v2.7支持长序列处理 在当前大语言模型&#xff08;LLM&#xff09;飞速发展的背景下&#xff0c;上下文长度的扩展已不再是锦上添花的功能&#xff0c;而是决定模型能否真正理解复杂文档、实现跨段落推理甚至长期对话记忆的关键能…

作者头像 李华
网站建设 2026/4/16 12:08:30

Git工作流规范:在PyTorch项目中实施Branch策略

Git工作流规范&#xff1a;在PyTorch项目中实施Branch策略 在现代AI团队的日常开发中&#xff0c;你是否经历过这样的场景&#xff1a;同事刚提交的代码导致整个训练流程崩溃&#xff0c;而问题原因竟是他本地装了不同版本的PyTorch&#xff1f;或者你在复现一篇论文实验时&…

作者头像 李华
网站建设 2026/4/13 7:29:29

分布式数据并行(DDP)配置:PyTorch-CUDA-v2.7多卡训练教程

分布式数据并行&#xff08;DDP&#xff09;配置&#xff1a;PyTorch-CUDA-v2.7多卡训练实战指南 在当今深度学习模型动辄数十亿参数的背景下&#xff0c;单张GPU早已无法支撑主流任务的训练需求。从大语言模型到高分辨率图像生成&#xff0c;算力瓶颈成为制约研发效率的关键因…

作者头像 李华
网站建设 2026/4/16 12:02:22

Jupyter密码设置与安全访问:PyTorch容器使用注意事项

Jupyter密码设置与安全访问&#xff1a;PyTorch容器使用注意事项 在如今的AI开发实践中&#xff0c;越来越多工程师选择在远程服务器或云平台上运行搭载 PyTorch 和 Jupyter 的 Docker 容器。这种组合极大提升了开发效率——无需繁琐配置即可快速进入模型调试环境。但随之而来的…

作者头像 李华
网站建设 2026/4/16 12:07:22

适合新手的5个爬虫工具软件,非常强大~

爬虫&#xff0c;又称为网络爬虫或网页爬虫&#xff0c;是一种自动浏览互联网的程序&#xff0c;它按照一定的算法顺序访问网页&#xff0c;并从中提取有用信息。爬虫软件通常由以下几部分组成&#xff1a; - 用户代理&#xff08;User-Agent&#xff09;&#xff1a;模拟浏览…

作者头像 李华