javascript事件循环在调用栈清空后自动轮询宏任务队列,每次取一个宏任务执行;宏任务结束后立即清空微任务队列,再进行下一轮宏任务;浏览器可能在宏任务与微任务后插入ui渲染。

JavaScript 的调用栈清空同步代码后,会立即检查并执行**任务队列(Task Queue)中的宏任务**,这个过程由事件循环(Event Loop)自动完成,不需要手动切换。
宏任务队列在调用栈为空时被轮询
当同步代码全部执行完毕、调用栈变为空时,事件循环会从**宏任务队列(如 setTimeout、setInterval、I/O、UI 渲染等回调)中取出最老的一项**,推入调用栈执行。这是一次“轮询”,不是切换,也不需要开发者干预。
- 每次只取一个宏任务执行,执行完再次清空调用栈
- 执行宏任务过程中产生的新同步代码会先填满调用栈,再触发下一轮轮询
- 注意:微任务队列(如 Promise.then、queueMicrotask)优先级更高,会在每次宏任务结束后、下个宏任务开始前清空
微任务总是在宏任务之间插队执行
宏任务执行完后,事件循环不会直接取下一个宏任务,而是先检查并**一次性执行完所有当前微任务队列里的任务**,再继续宏任务队列。
- 例如:setTimeout 回调(宏任务)里 resolve 一个 Promise,其 then 回调会进入微任务队列,立刻执行,而不是等到下次宏任务
- 微任务没有“队首等待”机制,只要存在,就会被连续执行直到队列为空
浏览器渲染与宏任务的时机关系
在某些环境下(如浏览器),一次宏任务执行完、微任务清空后,如果到了帧刷新时机,会插入一次**UI 渲染**,然后再继续下一轮宏任务。这属于宿主环境行为,并非 JS 引擎本身逻辑,但会影响任务感知顺序。
- requestAnimationFrame 的回调属于宏任务,但会在下一次渲染前执行
- 长时间运行的同步代码会阻塞宏任务和渲染,导致页面卡顿
没有“主动切换”的 API,只有调度和等待
你不能用代码命令 JS “现在去执行任务队列”,只能通过异步 API(如 setTimeout、Promise、postMessage)把任务**排入对应队列**,然后由事件循环按规则消费。
- 想让某段逻辑延后执行,用 setTimeout(fn, 0) 或 Promise.resolve().then(fn)
- setTimeout(fn, 0) 不是立刻执行,而是进入宏任务队列,等当前调用栈和微任务都处理完才执行
- Promise.then(fn) 是微任务,保证在本轮宏任务结束前执行
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











