Promise.resolve 与新的 Promise(resolve)
Posted
技术标签:
【中文标题】Promise.resolve 与新的 Promise(resolve)【英文标题】:Promise.resolve vs new Promise(resolve) 【发布时间】:2014-12-29 22:22:27 【问题描述】:我正在使用 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
只是糖。
简短回答 - 用法没有差异。只是糖。
@Pinal 什么是“糖”?
@Taurus。 语法糖 是旨在使事物更易于阅读或表达的语法。见:wikipedia.
【参考方案1】:
与 cmets 中的两个答案相反 - 存在差异。
虽然
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
ables,因此即使someObject
实际上是一个承诺本身,它也可以工作。
一般来说,Promise.resolve
用于将对象和外部承诺(thenables)转换为承诺。这就是它的用例。
【讨论】:
“Promise 返回函数通常应该保证它们不应该同步抛出,因为它们可能会异步抛出”。您能否详细说明为什么函数应该是同步的或异步的,而不是两者兼而有之?目前我喜欢 Promise.resolve(),你会说使用Promise.resolve()
是一种反模式吗?
@AshleyCoolman 请参阅blog.izs.me/post/59142742143/designing-apis-for-asynchrony - 一种有时行为异步的方法应该始终这样做以保持一致性。
Promise.resolve()
是否以与使用new
相同的方式创建Promise
的新实例?如果没有,return Promise.resolve(yourCode)
会更快并避免同步抛出。
我感觉不好,我使用“Promise.resolve().then(function() /*case that can throw an error*/).then...”来确保错误变成了被拒绝的承诺......我会更多地研究“Promise.method”
@Polopollo 或 Promise.coroutine
更有用。【参考方案2】:
上面的答案或cmets没有提到另一个区别:
如果 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");
);
第二个 sn-p 将首先打印 '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
调用将首先运行。
【讨论】:
以上是关于Promise.resolve 与新的 Promise(resolve)的主要内容,如果未能解决你的问题,请参考以下文章
Promise.resolve()与new Promise(r =; r(v))