Javascript Promise.resolve vs new Promise(resolve)
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/26711243/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Promise.resolve vs new Promise(resolve)
提问by Pipo
I'm using bluebird and I see two ways to resolve synchronous functions into a Promise, but I don't get the differences between both ways. It looks like the stacktrace is a little bit different, so they aren't just an alias, right?
我正在使用 bluebird,我看到了两种将同步函数解析为 Promise 的方法,但我不明白这两种方法之间的区别。看起来堆栈跟踪有点不同,所以它们不仅仅是一个alias,对吧?
So what is the preferred way?
那么什么是首选方式?
Way A
方式A
function someFunction(someObject) {
return new Promise(function(resolve) {
someObject.resolved = true;
resolve(someObject);
});
}
Way B
方式B
function someFunction(someObject) {
someObject.resolved = true;
return Promise.resolve(someObject);
}
采纳答案by Benjamin Gruenbaum
Contrary to both answers in the comments - there is a difference.
与评论中的两个答案相反 - 有区别。
While
尽管
Promise.resolve(x);
is basically the same as
基本上是一样的
new Promise(function(r){ r(x); });
there is a subtlety.
有一种微妙之处。
Promise returning functions should generally have the guarantee that they should not throw synchronously since they might throw asynchronously. In order to prevent unexpected results and race conditions - throws are usually converted to returned rejections.
Promise 返回函数通常应该保证它们不应该同步抛出,因为它们可能会异步抛出。为了防止意外结果和竞争条件 - 通常将抛出转换为返回的拒绝。
With this in mind - when the spec was created the promise constructor is throw safe.
考虑到这一点 - 创建规范时,promise 构造函数是安全的。
What if someObjectis undefined?
如果someObject是undefined?
- Way A returns a rejected promise.
- Way B throws synchronously.
- 方式 A 返回一个被拒绝的承诺。
- 方式B同步抛出。
Bluebird saw this, and Petka added Promise.methodto address this issue so you can keep using return values. So the correct and easiest way to write this in Bluebird is actually neither - it is:
Bluebird 看到了这一点,Petka 添加Promise.method了解决此问题的方法,以便您可以继续使用返回值。因此,在 Bluebird 中编写此内容的正确且最简单的方法实际上两者都不是 - 它是:
var someFunction = Promise.method(function someFunction(someObject){
someObject.resolved = true;
return someObject;
});
Promise.method will convert throws to rejects and returns to resolves for you. It is the most throw safe way to do this and it assimilatesthenables through return values so it'd work even if someObjectis in fact a promise itself.
Promise.method 会为你将 throws 转换为 rejects 并返回到 resolves。这是执行此操作的最安全的方法,它then通过返回值吸收能力,因此即使someObject实际上是承诺本身,它也可以工作。
In general, Promise.resolveis used for casting objects and foreign promises (thenables) to promises. That's its use case.
通常,Promise.resolve用于将对象和外部承诺(thenables)转换为承诺。这就是它的用例。
回答by edvard chen
There is another difference not mentioned by above answers or comments:
上面的答案或评论没有提到另一个区别:
If someObjectis a Promise, new Promise(resolve)would cost two additional tick.
如果someObject是Promise,new Promise(resolve)将花费两个额外的刻度。
Compare two following code snippet:
比较以下两个代码片段:
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");
});
The second snippet would print 'tick 3' firstly. Why?
第二个片段将首先打印“tick 3”。为什么?
If the value is a promise,
Promise.resolve(value)would return value exactly.Promise.resolve(value) === valuewould be true. see MDNBut
new Promise(resolve => resolve(value))would return a new promise which has locked in to follow thevaluepromise. It need extra one tick to make the 'locking-in'.// something like: addToMicroTaskQueue(() => { p.then(() => { /* resolve newly promise */ }) // all subsequent .then on newly promise go on from here .then(() => { console.log("tick 3"); }); });The
tick 1.thencall would run first.
如果值是一个承诺,
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通话将首先运行。
References:
参考:

