繁体   English   中英

Promise.resolve vs new Promise(resolve)

[英]Promise.resolve vs new Promise(resolve)

我正在使用 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);
}

与评论中的两个答案相反 - 有区别。

尽管

Promise.resolve(x);

基本上是一样的

new Promise(function(r){ r(x); });

有一种微妙之处。

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

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

如果someObject undefined怎么办?

  • 方式 A 返回一个被拒绝的承诺。
  • 方式B同步抛出。

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

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

Promise.method 会为你将 throws 转换为 rejects 并返回到 resolves。 这是执行此操作的最安全的方法,它通过返回值吸收then因此即使someObject实际上是一个承诺本身,它也可以工作。

通常, Promise.resolve用于将对象和外部承诺(thenables)转换为承诺。 这就是它的用例。

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

如果someObjectPromise ,则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(resolve => setTimeout(resolve)); 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))会返回一个新的 promise,该 promise 已锁定以遵循value promise。 它需要一个额外的滴答声来进行“锁定”。

     // 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调用将首先运行。


参考:

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM