Promise的异步性源于事件循环机制:executor同步执行,状态变更同步,但then回调被推入微任务队列异步执行;微任务优先于宏任务;链式调用返回新Promise并受微任务调度;reject同步但错误传播异步。

Promise 的异步特性不是靠“延迟执行”来伪装的,而是由 JavaScript 事件循环机制和 Promise 状态变更时机共同决定的。它表面上同步创建、同步注册回调,但真正触发回调的时机一定是异步的——哪怕 resolve 是立刻调用的。
构造函数和 then 是同步的,但回调执行是异步的
当你写 new Promise((resolve) => { resolve(1); }),里面的 executor 函数会立即执行(同步),resolve(1) 也同步调用。但注意:此时 Promise 状态确实变成 fulfilled,可 .then() 里传入的回调函数并不会马上运行。
它会被推入微任务队列(microtask queue),等待当前同步代码执行完、本轮事件循环结束之后,才在下一轮事件循环开始前执行。这就是 Promise 异步性的核心体现——状态变更同步,回调执行异步。
微任务队列保证执行顺序和优先级
Promise 回调属于微任务(microtask),比 setTimeout 的宏任务(macrotask)更早执行。比如:
- 同步代码先执行
- 然后所有已 resolve/reject 的 Promise 的
then/catch回调依次执行(按注册顺序) - 最后才轮到 setTimeout、setInterval 等宏任务
这种机制让 Promise 能“插队”式地响应异步结果,既避免阻塞主线程,又比传统回调更可控、更可预测。
链式调用天然支持异步流程编排
.then() 总是返回一个新 Promise,它的状态取决于回调函数的返回值或抛出的错误:
- 返回普通值 → 新 Promise 立即 fulfilled
- 返回另一个 Promise → 新 Promise 等待它完成
- 抛出错误 → 新 Promise 变为 rejected
这意味着你可以把多个异步操作串成一条链,每一步都依赖上一步的结果,而整个链条的执行节奏仍由微任务调度控制,不会出现同步阻塞,也不会丢失错误上下文。
reject 不会中断同步栈,但错误传播是异步的
reject() 调用本身是同步的,但如果没有被 .catch() 或 .then(null, fn) 捕获,错误不会立刻抛出,而是等到 Promise 进入 rejected 状态后,在本轮微任务结束后、下一轮事件循环前触发未捕获异常(Uncaught Promise rejection)。这也说明:Promise 的错误处理机制本身也是异步的,和 try/catch 的同步捕获有本质区别。

















