new Promise((resolve)=>{resolve()}) 与 Promise.resolve() 等价吗

处理以下类型的时候这个两个方法感觉差不多

参数是一个 Promise 实例
参数是一个thenable对象
参数不是具有then方法的对象,或根本就不是对象

但我看有人说:promise.resolve(v)不等于new Promise(r => r(v)),因为如果 v 是一个 Promise 对象,前者会直接返回 v,而后者需要经过一系列的处理(主要是 PromiseResolveThenableJob)

阅读 7.8k
3 个回答

我自己做了一个详细的测试

先说结论:在v是一个promise实例的时候,promise.resolve(v)new Promise(r => r(v))有明显的差异

区别表现:new Promise(r => r(v))的.then()回调会被推迟两个时序(事件循环)

原因:new Promise(r => r(v))里浏览器会创建一个 PromiseResolveThenableJob 去处理这个 Promise 实例,这是一个微任务。具体分析如下

    // v是一个实例化的promise,且状态为fulfilled
    let v = new Promise(resolve => {
      console.log("begin");
      resolve("then");
    });

    // 在promise里面resolve一个状态为fulfilled的promise

    // 模式一 new Promise里的resolve()
    // begin->1->2->3->then->4 可以发现then推迟了两个时序
    // 推迟原因:浏览器会创建一个 PromiseResolveThenableJob 去处理这个 Promise 实例,这是一个微任务。
    // 等到下次循环到来这个微任务会执行,也就是PromiseResolveThenableJob 执行中的时候,因为这个Promise 实例是fulfilled状态,所以又会注册一个它的.then()回调
    // 又等一次循环到这个Promise 实例它的.then()回调执行后,才会注册下面的这个.then(),于是就被推迟了两个时序
    new Promise(resolve => {
      resolve(v);
    }).then((v)=>{
        console.log(v)
    });

    //  模式二 Promise.resolve(v)直接创建
    // begin->1->then->2->3->4 可以发现then的执行时间正常了,第一个执行的微任务就是下面这个.then
    // 原因:Promise.resolve()API如果参数是promise会直接返回这个promise实例,不会做任何处理
/*     Promise.resolve(v).then((v)=>{
        console.log(v)
    }); */

    new Promise(resolve => {
      console.log(1);
      resolve();
    })
      .then(() => {
        console.log(2);
      })
      .then(() => {
        console.log(3);
      })
      .then(() => {
        console.log(4);
      });

谢邀。

首先是题主说到的第一种情况,即把 Promise 作为构造函数使用,例如 new Promise(fn),这时候的 fn 是同步调用,然后返回一个 promise 的 instance。这部分的说明可见 ECMASCript Spec 里的这部分:

The Promise constructor is the %Promise% intrinsic object and the initial value of the Promise property of the global object. When called as a constructor it creates and initializes a new Promise object.

然后是题主说到的第二种情况,即把 Promise 作为静态对象,调用 Promise.resolve,这时候还是会返回一个 promise 的 instance。不过如果传入的是非 promise instance,会进行一个包装;而传入的是 promise instance,则不会进行这个额外的包装。这部分的说明可见 ECMAScript Spec 里的这部分:

The resolve function returns either a new promise resolved with the passed argument, or the argument itself if the argument is a promise produced by this constructor.

所以回到题主的问题,当 value 是一个 promise instance 的时候,这两种情况确实是不一样的。

新手上路,请多包涵

实例化promise时,resolve返回的是promise对象时,将会由返回的promise状态决定原实例化promise的状态

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏