news 2026/2/16 19:29:47

面试题:了解事件循环吗

作者头像

张小明

前端开发工程师

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/2/16 14:37:28

本地无GPU也能调试?云端加载PyTorch-CUDA镜像进行推理

本地无GPU也能调试&#xff1f;云端加载PyTorch-CUDA镜像进行推理 在深度学习项目开发中&#xff0c;一个常见的尴尬场景是&#xff1a;你写好了模型代码、准备跑通推理流程&#xff0c;结果 torch.cuda.is_available() 返回了 False——本地没有 NVIDIA 显卡&#xff0c;连最基…

作者头像 李华
网站建设 2026/2/7 3:58:30

第四课Open3D点云数据处理:读写网格模型(mesh)与格式转换

1 mesh 加载函数 1.1 函数原型 1.2 参数说明 1.3代码展示 ​编辑 1.4 判断mesh文件是否读取成功 2 mesh 保存函数 2.1 函数原型 2.2 参数说明 2.3 代码示例 2.4 Open3D支持的mesh类型 3 mesh 格式转换 3.1 ply 转 obj 3.2 ply 转 stl 3.3 ply 转 off 3.4 ply 转…

作者头像 李华
网站建设 2026/2/16 11:35:39

第六课Open3D点云数据处理:点云、mesh可视化(Visualizer类)

1 Visualizer类 2 参数详解 2.1 常用参数 2.2 渲染参数 RenderOption 详解 3 点云可视化 3.1 最简单的点云可视化 3.2 可视化多个点云 3.3 可视化点云法线 3.4 其他参数 4 mesh可视化 4.1 最简单的mesh可视化 4.2 可视化三角网格和模型内表面 4.3 可视化多个mesh 1…

作者头像 李华
网站建设 2026/2/16 17:23:57

深度解析大模型微调技术:LoRA、QLoRA、DPO全对比,建议收藏!

深度解析2025年大模型微调技术&#xff1a;LoRA、QLoRA、DPO全对比&#xff0c;建议收藏&#xff01; 文章系统介绍了大语言模型微调技术的演进与现状&#xff0c;重点分析了参数高效微调(PEFT)的革命性技术&#xff0c;包括LoRA及其改进版QLoRA、VeRA、DoRA和AdaLoRA&#xff…

作者头像 李华
网站建设 2026/1/29 21:24:01

为什么越来越多开发者选择PyTorch-CUDA预装镜像?

为什么越来越多开发者选择PyTorch-CUDA预装镜像&#xff1f; 在深度学习项目启动的前48小时里&#xff0c;你更愿意把时间花在模型设计上&#xff0c;还是反复折腾CUDA版本和驱动兼容性&#xff1f;这几乎是每个AI工程师都经历过的灵魂拷问。而如今&#xff0c;越来越多团队正在…

作者头像 李华