promise 的执行完全依赖事件循环的微任务机制:其回调总在当前宏任务结束后、下一宏任务开始前批量执行,thus 总比同级 settimeout 先运行;async/await 是 promise 微任务的语法糖,状态切换与回调执行解耦,确保行为可预测。

Promise 不是独立存在的异步容器,它从诞生起就深度绑定 JavaScript 的事件循环机制——它的执行时机、错误传播路径、链式行为,全都由微任务队列的调度规则决定。
Promise 的回调走的是微任务,不是宏任务
当你调用 Promise.resolve().then(...),这个回调不会被放进 setTimeout 那样的宏任务队列,而是直接进入微任务队列。这意味着:它一定在当前同步代码执行完后、下一个宏任务开始前被执行。
- 宏任务(如
setTimeout、setInterval、I/O、UI 渲染)之间会插入一次完整的微任务清空过程 - 哪怕你在
then回调里再创建一个Promise.then,它也会被立刻加入微任务队列,而不是等下一轮事件循环 - 这正是 Promise 链能“看似同步”执行、避免中间卡顿的关键
事件循环决定了 Promise.then 的实际执行顺序
一段代码的输出顺序,不能只看书写位置,而要看它落在哪个任务类型里:
- 同步语句(
console.log)直接进调用栈,立刻执行 -
setTimeout注册的函数会被推入宏任务队列,等待本轮微任务清空后才轮到 -
Promise.then注册的函数被推入微任务队列,在当前宏任务末尾集中执行 - 所以
Promise.then总比同级setTimeout先输出,哪怕写在后面
async/await 是 Promise + 微任务的语法糖
await 并没有引入新机制,它只是让引擎自动把后续代码包装成 Promise.then 回调,并确保该回调进入微任务队列。
-
await promise等价于promise.then(value => { /* 后续代码 */ }) - 函数被标记为
async后,返回值自动包装成 Promise,即使你return 42 - 错误处理也统一交由 Promise 的
reject路径,最终落入catch或try/catch
Promise 状态机与事件循环协同工作
Promise 本身是个状态有限机(Pending → Fulfilled/Rejected),但它不主动“驱动”执行;真正触发回调的是事件循环对微任务队列的消费。
- 构造函数里的执行器(executor)是同步运行的,
resolve()或reject()一调用,状态就切换,但回调并不立即执行 - 回调被注册进微任务队列,要等到当前宏任务结束、微任务队列被清空时才批量执行
- 这种分离设计保证了 Promise 行为可预测:状态变化和副作用执行解耦,避免竞态和意外重入











