news 2026/4/17 23:03:20

面试题:了解事件循环吗

作者头像

张小明

前端开发工程师

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 9:25:42

浏览器输入url后。。。

面试回答&#xff08;结构化 技术细节&#xff09;&#xff1a; 当在浏览器地址栏输入一个 URL 并按下回车后&#xff0c;整个过程大致可以分为以下几个阶段&#xff1a;1. URL 解析 浏览器首先解析输入的 URL&#xff0c;判断是否为合法格式。如果没有协议&#xff08;如 htt…

作者头像 李华
网站建设 2026/4/17 17:50:35

PyTorch训练速度提升5倍?关键在于正确使用CUDA镜像

PyTorch训练速度提升5倍&#xff1f;关键在于正确使用CUDA镜像 在深度学习项目中&#xff0c;你是否经历过这样的场景&#xff1a;刚写完一个新模型&#xff0c;满心期待地按下运行键&#xff0c;结果发现训练一轮要两个小时&#xff1f;查看资源监控才发现——GPU利用率只有10…

作者头像 李华
网站建设 2026/4/12 0:26:48

QLoRA量化微调教程:结合PyTorch-CUDA-v2.7节省显存开销

QLoRA量化微调实战&#xff1a;基于PyTorch-CUDA-v2.7实现高效显存管理 在大模型时代&#xff0c;一个现实问题摆在每个开发者面前&#xff1a;如何用一张消费级显卡微调70亿参数以上的语言模型&#xff1f;传统全量微调动辄需要80GB显存&#xff0c;而QLoRA的出现彻底改变了这…

作者头像 李华
网站建设 2026/4/8 6:07:47

Git下载大型项目配合PyTorch-CUDA镜像实现端到端开发流程

Git下载大型项目配合PyTorch-CUDA镜像实现端到端开发流程 在深度学习项目日益庞大的今天&#xff0c;一个典型模型仓库动辄几十GB——不仅包含成千上万行代码&#xff0c;还有预训练权重、数据集链接、文档资源和复杂的依赖树。当你试图复现一篇论文或接手团队项目时&#xff0…

作者头像 李华
网站建设 2026/4/16 5:19:10

使用PyTorch-CUDA-v2.7镜像快速启动Transformer文本生成任务

使用PyTorch-CUDA-v2.7镜像快速启动Transformer文本生成任务 在大模型遍地开花的今天&#xff0c;一个常见的场景是&#xff1a;你刚找到一篇惊艳的论文&#xff0c;迫不及待想复现它的文本生成效果。但还没开始写代码&#xff0c;就卡在了环境配置上——Python版本不对、PyTor…

作者头像 李华
网站建设 2026/4/7 14:46:07

PyTorch 2.7版本新特性一览:结合CUDA镜像提升推理速度

PyTorch 2.7版本新特性一览&#xff1a;结合CUDA镜像提升推理速度 在AI模型日益复杂、部署节奏不断加快的今天&#xff0c;一个常见的痛点浮出水面&#xff1a;为什么本地能跑通的代码&#xff0c;换台机器就报“CUDA not available”&#xff1f;为什么训练完的模型一上线&…

作者头像 李华