Promise.resolve vs new Promise(解决)

时间:2014-11-03 09:27:19

标签: javascript promise bluebird

我使用蓝鸟,我看到两种方法可以将同步功能解析为Promise,但我并不知道两种方式之间的差异。看起来堆栈跟踪有点不同,所以它们不仅仅是alias,对吧?

那么首选方式是什么?

方式A

function someFunction(someObject) {
  return new Promise(function(resolve) {
    someObject.resolved = true;
    resolve(someObject);
  });
}

方式B

function someFunction(someObject) {
  someObject.resolved = true;
  return Promise.resolve(someObject);
}

2 个答案:

答案 0 :(得分:67)

与评论中的两个答案相反 - 存在差异。

虽然

Promise.resolve(x);

基本相同
new Promise(function(r){ r(x); });

有一个微妙的。

Promise返回函数通常应该保证它们不应该同步抛出,因为它们可能异步抛出。为了防止出现意外结果和竞争条件 - 投掷通常会转换为退回拒绝。

考虑到这一点 - 在创建规范时,promise构造函数是安全的。

如果someObjectundefined

,该怎么办?
  • 方式A返回被拒绝的承诺。
  • B路同步投掷。

Bluebird看到了这一点,Petka添加了Promise.method来解决此问题,因此您可以继续使用返回值。所以在Bluebird中写这个的正确和最简单的方法实际上都不是 - 它是:

var someFunction = Promise.method(function someFunction(someObject){
    someObject.resolved = true;
    return someObject;
});

Promise.method会将throws转换为拒绝并返回为你解析。这是最安全的方法,它通过返回值吸收then个ables,所以即使someObject实际上是一个承诺本身,它也能正常工作。

通常,Promise.resolve用于将对象和外国承诺(可能)投射到承诺。这就是它的用例。

答案 1 :(得分:7)

以上答案或评论中没有提到的另一个区别:

如果someObject是待处理的Promise,则new Promise(resolve)将花费额外的时间。


比较以下两个代码段:

const p = new Promise(resovle => setTimeout(resovle));

new Promise(resolve => resolve(p)).then(() => {
  console.log("tick 3");
});

p.then(() => {
  console.log("tick 1");
}).then(() => {
  console.log("tick 2");
});

const p = new Promise(resovle => setTimeout(resovle));

Promise.resolve(p).then(() => {
  console.log("tick 3");
});

p.then(() => {
  console.log("tick 1");
}).then(() => {
  console.log("tick 2");
});

第二个代码段将首先打印“ tick 3”。为什么?

  • 如果该值是一个承诺,则Promise.resolve(value)将精确返回值。 Promise.resolve(value) === value是正确的。参见MDN

  • 但是new Promise(resolve => resolve(value))将返回一个新的承诺,该承诺已锁定以遵守value的承诺。需要额外的一个勾号才能进行“锁定”。

    // something like:
    addToMicroTaskQueue(() => {
      p.then(() => {
        /* resolve newly promise */
      })
        // all subsequent .then on newly promise go on from here
        .then(() => {
          console.log("tick 3");
        });
    });
    

    tick 1 .then调用将首先运行。


参考文献: