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

为何Promise已解析为另一个Promise时状态仍显示pending?

Promise状态与微任务队列的疑问解析

先看代码片段:

var p3 = new Promise( function(resolve,reject){
    resolve( "B" );
} );
var p1 = new Promise( function(res,rej){
  resolve( p3 ); // equivalent to p3.then(res)
} );
var p2 = new Promise( function(resolve,reject){
    resolve( "A" );
} );
p1.then( function(v){
    console.log("In p1");
    console.log(p1);
} );
p2.then( function(v){
    console.log("In p2");
    console.log(p1);
} ); 

实际运行日志顺序是In p2先输出,且此时console.log(p1)显示pending,之后In p1输出,p1显示fulfilled。以下是对你的疑问和阶段理解的纠正:


纠正你对执行阶段的错误理解

  1. Stage 1:resolve(p3)确实等价于p3.then(res),但res('B')的执行是异步的——不会在同步代码阶段立刻触发,所以此时p1的状态仍为pending。你说这个回调会被加入微任务队列(MTQ)是对的,但它的执行时机是在同步代码结束后,且实际运行中会排在p2的then回调之后。
  2. Stage 2:p2的then回调被加入MTQ是对的,但此时MTQ中的顺序是p2的回调在前,p1的resolve回调在后,所以后续会先执行p2的回调。
  3. Stage 3:调用栈为空时,MTQ按先入先出执行,但你之前假设的执行顺序有误,实际是先执行p2的then回调,此时p1的resolve回调还没执行,所以p1仍为pending。

你的疑问解答

  1. 当res('B')执行时,是否会将p1的状态标记为Fulfilled?
    是的。res就是p1绑定的resolve回调,调用它会同步把p1的状态改成fulfilled,并设置值为"B"。问题在于res('B')的执行是异步的,不会在同步代码阶段跑。

  2. 既然p1已完成且已注册处理函数,是否会被追加到MTQ中?
    是的。一旦p1的状态变为fulfilled,之前通过p1.then注册的回调会被立即加入MTQ,等待执行。

  3. 为何此时p1仍显示为pending?
    这里的"此时"指p2的then回调执行时,因为p2的then回调在MTQ中排在p1的resolve回调前面,先被执行了。此时p1的resolve回调还没来得及执行,所以状态还是pending。

  4. 后续p1为何突然变为fulfilled状态?
    p2的then回调执行完后,MTQ的下一个任务就是p1的resolve回调(也就是执行res('B')),这个任务执行时会把p1的状态改成fulfilled。之后p1的then回调被加入MTQ并执行,此时打印p1就会显示fulfilled。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 23:19:51