Promise.resolve vs new Promise(解决)

Pip*_*ipo 77 javascript promise bluebird

我正在使用蓝鸟,我看到两种方法将同步函数解析为Promise,但我没有得到两种方式之间的差异.看起来堆栈跟踪有点不同,所以它们不仅仅是一个alias,对吧?

那么首选方式是什么?

方式A.

function someFunction(someObject) {
  return new Promise(function(resolve) {
    someObject.resolved = true;
    resolve(someObject);
  });
}
Run Code Online (Sandbox Code Playgroud)

方式B.

function someFunction(someObject) {
  someObject.resolved = true;
  return Promise.resolve(someObject);
}
Run Code Online (Sandbox Code Playgroud)

Ben*_*aum 72

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

Promise.resolve(x);
Run Code Online (Sandbox Code Playgroud)

基本上是一样的

new Promise(function(r){ r(x); });
Run Code Online (Sandbox Code Playgroud)

有一个微妙的.

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

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

如果someObject是的话undefined

  • 方式A返回被拒绝的承诺.
  • B路同步投掷.

Bluebird看到了这一点,Petka补充说明Promise.method了这个问题,所以你可以继续使用返回值.所以在Bluebird中写这个的正确和最简单的方法实际上都不是 - 它是:

var someFunction = Promise.method(function someFunction(someObject){
    someObject.resolved = true;
    return someObject;
});
Run Code Online (Sandbox Code Playgroud)

Promise.method会将throws转换为拒绝并返回为你做出决定.这是最安全的方式,它then通过返回值吸收能量,所以它即使someObject实际上是一个承诺本身也能工作.

一般来说,Promise.resolve用于铸造物品和外国承诺(可能)承诺.这是它的用例.

  • @AshleyCoolman参见http://blog.izs.me/post/59142742143/designing-apis-for-asynchrony-为保证一致性,_sometimes_应该异步行为的方法。 (2认同)

edv*_*hen 12

上面的答案或评论没有提到另一个差异:

如果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");
});
Run Code Online (Sandbox Code Playgroud)

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");
});
Run Code Online (Sandbox Code Playgroud)

第二个片段将首先打印“ 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");
        });
    });
    
    Run Code Online (Sandbox Code Playgroud)

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


参考文献: