[英]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
怎么办? 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)转换为承诺。 这就是它的用例。
上述答案或评论中没有提到的另一个区别:
如果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(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.