event loop严格分离宏任务与微任务队列,每次执行一个宏任务后立即清空全部微任务(含新产生的),微任务中注册的宏任务须等到下一轮循环首个宏任务位置才执行。

Event Loop 不会把微任务塞进宏任务里执行,也不会让宏任务“嵌套”在微任务中运行。它有一套固定的调度规则:微任务永远在当前宏任务结束后、下一个宏任务开始前被**一次性清空**;而宏任务只能排队等待下一轮循环,不能插队。
宏任务执行过程中产生的微任务
宏任务(比如 setTimeout 回调)内部如果触发了 Promise.then、queueMicrotask 或 MutationObserver,这些微任务不会等当前宏任务“做完再统一处理”,而是立刻被加入微任务队列尾部,并在当前宏任务结束后的**同一轮清空阶段**被执行。
- 例如:
setTimeout(() => { console.log('A'); Promise.resolve().then(() => console.log('B')); }, 0),输出一定是 A → B - 哪怕这个 Promise.then 又创建了新的 Promise.then,它们也会链式追加到微任务队列末尾,继续执行直到队列为空
微任务中产生的宏任务
微任务(比如 Promise.then 回调)里调用 setTimeout、setInterval 或发起一个 fetch,这些操作只会把对应回调推入**宏任务队列**,但不会触发立即执行。
Java JDK 25 来自 OpenJDK 官方归档,版本为 JDK 25,本条下载地址已指向官方 Windows x64 zip 安装包直链,适合调试旧项目或兼容旧版 Java 运行环境。
- 它们要等到当前所有微任务执行完毕、本次事件循环迭代结束之后,才可能在**下一轮循环的第一个宏任务位置**被取出
- 也就是说:微任务里写
setTimeout(..., 0),它比当前正在执行的任何微任务都“慢”,甚至比下一个宏任务还晚(因为下一轮循环先清微任务,再取宏任务)
关键逻辑:队列分离 + 执行时机锁定
宏任务队列和微任务队列是物理隔离的两个结构,Event Loop 每次只从宏任务队列取一个任务,执行完后强制清空整个微任务队列——不管这个微任务是哪来的,也不管它里面又生成了多少新微任务。
- 微任务可以“递归”生成微任务,但不能“触发”宏任务提前执行
- 宏任务可以“顺带”注册微任务,但不能阻止微任务清空流程
- 没有“微任务中的宏任务立即执行”这回事,也没有“宏任务中途暂停去跑另一个宏任务”的情况
不复杂但容易忽略:宏与微的优先级不是靠“谁先写”,而是靠“谁在哪一环被放入哪个队列”。写的位置决定归属,执行的时机由 Event Loop 严格控制。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










