javascript事件循环中不存在“挂起队列”;实际存在的是宏任务队列(存放settimeout、i/o等)和微任务队列(存放promise.then、mutationobserver等),二者均为fifo结构,执行顺序为:同步代码→微任务队列清空→一个宏任务→重复循环。

JavaScript 的事件循环(Event Loop)中并没有一个叫“挂起队列”的标准术语。你可能指的是 任务队列(Task Queue,也称宏任务队列)、微任务队列(Microtask Queue),或者对某些异步操作(如 pending 的 Promise、未 resolve/reject 的定时器、I/O 等)处于“等待状态”的误解。
宏任务队列(Macrotask Queue)
这是事件循环中明确存在的队列,用于存放宏任务(macrotask),例如:
- setTimeout / setInterval 回调
- I/O 操作完成后的回调(如 fs.readFile)
- UI 渲染后的回调(如 requestIdleCallback)
- script 标签的初始执行(主代码块)
每次事件循环迭代,仅从宏任务队列中取出一个任务执行,执行完后会清空微任务队列(见下)。
微任务队列(Microtask Queue)
它不是“挂起”状态,而是高优先级、立即执行的队列,在每次宏任务执行结束后、渲染前被清空:
Java Linux版下载入口,提供 Oracle JDK 26.0.2 官方 Linux 安装包、Java 环境配置、JDBC 数据库连接和 Java 服务端开发相关信息。
- Promise.then/catch/finally 的回调
- queueMicrotask() 插入的任务
- MutationObserver 回调
注意:微任务队列是先进先出(FIFO),且会持续执行直到为空——哪怕中间又加入新微任务,也会一并执行完才继续下一个宏任务。
没有“挂起队列”,但有 pending 状态的异步操作
像 new Promise(() => {}) 这样的 Promise 本身处于 pending 状态,但它不进入任何队列,只是 JS 引擎内部的一个对象状态。只有当它被 resolve 或 reject 后,对应的 .then 回调才会被推入微任务队列。
- pending 的 Promise 不排队,也不触发调度
- 未到时间的 setTimeout 也不会进宏任务队列,只在到期时由宿主环境(如浏览器/V8)将其加入
- await 后面的 Promise pending 时,当前 async 函数暂停,控制权交还事件循环,但 await 本身不产生队列项
如何观察和分析实际队列行为
靠打印 + 逻辑推理是最常用方式,例如:
- 用 console.log 配合 setTimeout(0) 和 Promise.resolve().then() 对比执行顺序
- 使用 Chrome DevTools 的 Performance 面板录制,查看 Tasks 和 Microtasks 的时间线
- Node.js 中可通过
process.nextTick()(类微任务但优先级更高)辅助验证调度时机
关键原则:宏任务一次一个,微任务一次清空,pending 状态不占队列资源。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










