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
相关产品推荐
相关产品推荐

