我使用蓝鸟,我看到两种方法可以将同步功能解析为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);
}
答案 0 :(得分:67)
与评论中的两个答案相反 - 存在差异。
虽然
Promise.resolve(x);
与
基本相同new Promise(function(r){ r(x); });
有一个微妙的。
Promise返回函数通常应该保证它们不应该同步抛出,因为它们可能异步抛出。为了防止出现意外结果和竞争条件 - 投掷通常会转换为退回拒绝。
考虑到这一点 - 在创建规范时,promise构造函数是安全的。
someObject
是undefined
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
调用将首先运行。
参考文献: