You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Promise回调函数的触发时机及执行顺序问题

Promise的then回调执行时机与触发条件

问题背景

执行以下代码:

const p = new Promise((resolve, reject) => {
    resolve('resolved');
});
p.then((r) => console.log(r));
console.log('hi!');

运行后会先输出hi!,再输出resolved。这说明then的回调函数是在console.log('hi!')之后执行的,显然它不会像推测的那样在Promise构造函数内部被直接调用。那么then的回调究竟什么时候执行?触发它的条件是什么?


核心解释

1. 执行时机:当前宏任务结束后,从微任务队列取出执行

JavaScript的代码执行依赖事件循环机制,任务分为两类:

  • 宏任务:全局同步代码、setTimeout/setInterval回调、I/O操作等
  • 微任务:Promise的then/catch/finally回调、Node.js环境的process.nextTick等

你的代码执行流程具体是:

  • 第一步:创建Promise实例时,构造函数里的回调是同步执行的,调用resolve('resolved')后,Promise状态立刻变为fulfilled(已完成)。
  • 第二步:调用p.then()时,因为Promise已经处于完成状态,对应的回调会被加入微任务队列,但不会立刻执行。
  • 第三步:执行同步代码console.log('hi!'),直接输出内容,这属于当前宏任务的一部分。
  • 第四步:当前宏任务的所有同步代码执行完毕后,事件循环会先清空微任务队列里的所有任务,此时才会执行then的回调,输出resolved。

2. 触发条件

then回调被加入微任务队列的核心触发条件是:Promise的状态从pending(等待)变为fulfilled(完成)或者rejected(拒绝)。

  • 调用resolve()时,then的第一个回调会被加入队列;
  • 调用reject()时,then的第二个回调或者catch的回调会被加入队列。

额外说明:如果调用then()时,Promise已经处于完成/拒绝状态(比如你例子里的情况),回调会被立即加入微任务队列;如果Promise还处于pending状态,回调会被暂存,直到Promise状态改变时才会被加入队列。


内容的提问来源于stack exchange,提问作者gib65

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 01:17:35