如何理解JavaScript微任务和宏任务_它们怎样影响事件循环

发布时间 - 2025-12-27 00:00:00    点击率:
JavaScript事件循环每轮只执行一个宏任务,随后清空全部微任务。宏任务如script、setTimeout、DOM事件等驱动循环节奏;微任务如Promise回调、queueMicrotask等在宏任务后立即批量执行,期间不插入宏任务或渲染。

JavaScript 的事件循环靠宏任务和微任务协同工作,不是“先宏后微”那么简单,而是“每轮只取一个宏任务,但紧跟着清空全部微任务”。理解这点,才能准确预判异步代码的执行顺序。

宏任务是事件循环的“节拍器”

宏任务定义了事件循环的基本节奏。每次循环只执行一个宏任务,比如:

  • 整个 script 脚本(初始执行)
  • setTimeout / setInterval 回调
  • 用户点击、滚动等 DOM 事件回调
  • fetch 响应完成、I/O 完成等系统级回调
  • 浏览器 UI 渲染(在微任务清空后触发)

它像一拍一拍的鼓点,推动事件循环向前走。没有宏任务,事件循环就停摆。

微任务是“插队者”,但只插在当前宏任务之后

微任务不开启新循环,只在当前宏任务执行完、下一个宏任务开始前集中执行。常见类型有:

  • Promise.then / .catch / .finally 的回调
  • queueMicrotask() 显式注册的任务
  • MutationObserver 的回调(监听 DOM 变化)
  • Node.js 中的 process.nextTick(仅限 Node 环境)

关键规则:只要微任务队列非空,就会持续执行直到清空,期间不会穿插任何宏任务或渲染。

一次完整的事件循环步骤

不是“宏→微→宏→微”,而是严格按以下四步循环:

  • 执行当前宏任务中的同步代码(压入/弹出调用栈)
  • 遇到 Promise.resolve().then(...),把回调推入微任务队列
  • 当前宏任务结束,立即执行所有排队的微任务(一个接一个,无中断)
  • 微任务队列清空后,浏览器可能进行 UI 渲染,然后从宏任务队列取下一个任务

例如:setTimeout(() => console.log(1))Promise.resolve().then(() => console.log(2)) 同时存在时,2 总是比 1 先输出——因为 setTimeout 是下一轮宏任务,而 Promise.then 是本轮宏任务结束后的微任务。

为什么这个区别很重要

它直接影响代码可预测性和性能表现:

  • 避免“微任务风暴”:连续调用 queueMicrotask 或递归 resolve Promise,会阻塞渲染和后续宏任务,导致页面卡顿
  • 控制更新时机:想确保 DOM 修改后立刻响应(如获取 offsetHeight),可用微任务;想让浏览器先渲染再处理(如动画帧后清理),要用 requestAnimationFrame 或 setTimeout
  • 调试异步逻辑:async/await 底层基于 Promise,所以 await 后的代码实际是微任务,不是同步语句

事件循环机制本身不复杂,但微任务的“清空式执行”容易被忽略,正是它让 JavaScript 在单线程下兼顾响应性与一致性。


# javascript  # java  # js  # node.js  # node  # 浏览器  #   # ai  # 区别  # 为什么 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: 高端建站如何打造兼具美学与转化的品牌官网?  Laravel集合Collection怎么用_Laravel集合常用函数详解  Win11怎么设置虚拟桌面 Win11新建多桌面切换操作【技巧】  Laravel队列由Redis驱动怎么配置_Laravel Redis队列使用教程  5种Android数据存储方式汇总  Laravel Docker环境搭建教程_Laravel Sail使用指南  儿童网站界面设计图片,中国少年儿童教育网站-怎么去注册?  如何快速辨别茅台真假?关键步骤解析  浅谈javascript alert和confirm的美化  Laravel怎么实现微信登录_Laravel Socialite第三方登录集成  Laravel如何实现数据导出到PDF_Laravel使用snappy生成网页快照PDF【方案】  网站建设保证美观性,需要考虑的几点问题!  网站制作软件有哪些,制图软件有哪些?  如何在七牛云存储上搭建网站并设置自定义域名?  Internet Explorer官网直接进入 IE浏览器在线体验版网址  Laravel与Inertia.js怎么结合_使用Laravel和Inertia构建现代单页应用  如何在IIS7上新建站点并设置安全权限?  Laravel怎么实现一对多关联查询_Laravel Eloquent模型关系定义与预加载【实战】  Laravel Fortify是什么,和Jetstream有什么关系  如何在建站主机中优化服务器配置?  Laravel如何生成API文档?(Swagger/OpenAPI教程)  Laravel如何实现全文搜索_Laravel Scout集成Algolia或Meilisearch教程  网页设计与网站制作内容,怎样注册网站?  javascript日期怎么处理_如何格式化输出  Laravel如何创建自定义Facades?(详细步骤)  PHP 500报错的快速解决方法  湖南网站制作公司,湖南上善若水科技有限公司做什么的?  韩国代理服务器如何选?解析IP设置技巧与跨境访问优化指南  PHP怎么接收前端传的文件路径_处理文件路径参数接收方法【汇总】  Android滚轮选择时间控件使用详解  HTML5建模怎么导出为FBX格式_FBX格式兼容性及导出步骤【指南】  西安专业网站制作公司有哪些,陕西省建行官方网站?  微信推文制作网站有哪些,怎么做微信推文,急?  Laravel如何实现URL美化Slug功能_Laravel使用eloquent-sluggable生成别名【方法】  创业网站制作流程,创业网站可靠吗?  bing浏览器学术搜索入口_bing学术文献检索地址  如何在万网主机上快速搭建网站?  在线制作视频网站免费,都有哪些好的动漫网站?  Laravel如何使用Scope本地作用域_Laravel模型常用查询逻辑封装技巧【手册】  如何自定义建站之星网站的导航菜单样式?  高性能网站服务器部署指南:稳定运行与安全配置优化方案  Laravel如何实现API版本控制_Laravel API版本化路由设计策略  如何在Windows虚拟主机上快速搭建网站?  千问怎样用提示词获取健康建议_千问健康类提示词注意事项【指南】  简历在线制作网站免费版,如何创建个人简历?  如何在IIS中新建站点并配置端口与物理路径?  如何快速配置高效服务器建站软件?  Laravel项目如何进行性能优化_Laravel应用性能分析与优化技巧大全  Laravel Eloquent关联是什么_Laravel模型一对一与一对多关系精讲  js实现获取鼠标当前的位置