关键在于宏任务结束后必须立即清空全部微任务队列,再取下一个宏任务;宏任务是事件循环节拍器,微任务是其收尾工作,二者严格按“宏任务→微任务清空→渲染→下一宏任务”四步循环执行。

关键不在“谁快谁慢”,而在于执行时机的强制约定:每个宏任务结束后,必须立刻清空全部微任务队列,之后才能取下一个宏任务。
宏任务是事件循环的“节拍器”
宏任务定义了一轮事件循环的起点和节奏。它包括:
– 整体 <script></script> 标签内容(第一个宏任务)
– setTimeout、setInterval
– 用户交互(如 click、input)
– UI 渲染(浏览器环境)
每次只取一个宏任务执行,执行完即停,不等第二个。
微任务是宏任务的“收尾工作”
微任务不是“插队”,而是被强制安排在宏任务结束后的固定窗口里执行。它包括:
– Promise.then/catch/finally
– queueMicrotask()
– MutationObserver 回调
只要微任务队列非空,就会持续取出执行,直到彻底清空——哪怕过程中又注册了新微任务,也照常加入队尾并本轮执行完。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
协作流程就是四步固定循环
浏览器或 Node.js 运行时严格按以下顺序推进:
– 执行一个宏任务(比如 setTimeout 回调)
– 遇到 Promise.then 等,把回调推入微任务队列
– 宏任务执行完毕,立即逐个执行微任务队列中的所有任务(先进先出)
– 微任务清空后,才进入下一轮:检查是否需要渲染(浏览器),再取下一个宏任务
典型代码能直接验证这个协作关系
看这段代码的输出顺序:
console.log(1);
setTimeout(() => console.log(2), 0);
Promise.resolve().then(() => console.log(3));
console.log(4);
执行过程:
– 同步部分先输出 1 和 4
– setTimeout 回调进宏任务队列;Promise.then 进微任务队列
– 脚本宏任务结束 → 立即执行微任务 → 输出 3
– 微任务队列空 → 下一轮 → 取出 setTimeout 宏任务 → 输出 2
最终顺序:1 → 4 → 3 → 2
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










