Promise回调属于微任务,其执行时机在当前宏任务结束后立即清空微任务队列时,优先于setTimeout等宏任务,如输出顺序为1→4→2→3,且规范中明确归入PromiseJobs微任务队列。

Promise 回调(.then()、.catch()、.finally() 中的函数)属于微任务,不是宏任务。
看执行时机:微任务在当前宏任务结束后立即执行
JavaScript 执行完一段同步代码(比如整个脚本或一个定时器回调),会立刻检查并清空微任务队列,然后再去取下一个宏任务。这意味着 Promise 回调总比同级的 setTimeout 先执行,哪怕延迟是 0:
-
console.log('1')→ 同步,立即输出 -
Promise.resolve().then(() => console.log('2'))→ 回调入微任务队列 -
setTimeout(() => console.log('3'), 0)→ 回调入宏任务队列 -
console.log('4')→ 同步,立即输出
输出顺序一定是 1 → 4 → 2 → 3,因为“2”所在的微任务在同步代码(1 和 4)结束后、下一个宏任务(3)之前被执行。
看规范定义:Promise.then() 回调明确进入微任务队列
ECMAScript 规范将 Promise 的履行(fulfill)或拒绝(reject)后触发的回调,归入 PromiseJobs 队列,这是微任务队列的标准实现之一。它和 MutationObserver 回调同级,优先级高于 setTimeout、setInterval、I/O 等宏任务。
立即学习“Java免费学习笔记(深入)”;
注意:new Promise(fn) 中的 fn 是同步执行的;只有 .then() 里的回调才是微任务。
看实际验证:用 queueMicrotask 对齐行为
queueMicrotask 是显式插入微任务的 API,它的执行时机和 Promise 回调完全一致:
Promise.resolve().then(() => console.log('p'))queueMicrotask(() => console.log('q'))setTimeout(() => console.log('t'), 0)
输出一定是 p → q → t。两者行为一致,进一步印证 Promise 回调属于微任务。
常见误区提醒
容易混淆的点:
-
setTimeout(fn, 0)不是“立刻执行”,而是“最早可调度时入宏任务队列” -
Promise.resolve().then(fn)的fn不是“马上调用”,而是“当前任务一结束就执行”,即微任务语义 - 链式调用中每个
.then()返回的新 Promise,其回调仍按微任务规则入队,不受前一个 resolve 时间影响


















