[英]What's the difference between returning value or Promise.resolve from then()
What is the difference between:有什么区别:
new Promise(function(res, rej) { res("aaa"); }).then(function(result) { return "bbb"; // directly returning string }).then(function(result) { console.log(result); });
and this:和这个:
new Promise(function(res, rej) { res("aaa"); }).then(function(result) { return Promise.resolve("bbb"); // returning a promise }).then(function(result) { console.log(result); });
I'm asking as I'm getting different behaviour Using Angular and $http service with chaining.then().我在问,因为我使用 Angular 和 $http 服务与 chaining.then() 得到不同的行为。 A bit too much code hence first the example above.
代码有点多,因此首先是上面的示例。
In simple terms, inside a then
handler function:简单来说,在
then
处理函数中:
A) When x
is a value (number, string, etc): A) 当
x
是一个值(数字、字符串等)时:
return x
is equivalent to return Promise.resolve(x)
return x
等价于return Promise.resolve(x)
throw x
is equivalent to return Promise.reject(x)
throw x
等价于return Promise.reject(x)
B) When x
is a Promise that is already settled (not pending anymore): B) 当
x
是一个已经解决(不再挂起)的 Promise 时:
return x
is equivalent to return Promise.resolve(x)
, if the Promise was already resolved. return x
等价于return Promise.resolve(x)
,如果 Promise 已经解决了。return x
is equivalent to return Promise.reject(x)
, if the Promise was already rejected.return x
等效于return Promise.reject(x)
。 C) When x
is a Promise that is pending: C) 当
x
是一个待定的 Promise 时:
return x
will return a pending Promise, and it will be evaluated on the subsequent then
. return x
将返回一个挂起的 Promise,并将在随后的then
上进行评估。 Read more on this topic on the Promise.prototype.then() docs .在Promise.prototype.then() 文档中阅读有关此主题的更多信息。
The rule is, if the function that is in the then
handler returns a value, the promise resolves/rejects with that value, and if the function returns a promise, what happens is, the next then
clause will be the then
clause of the promise the function returned , so, in this case, the first example falls through the normal sequence of the thens
and prints out values as one might expect, in the second example, the promise object that gets returned when you do Promise.resolve("bbb")
's then is the then
that gets invoked when chaining(for all intents and purposes).规则是,如果
then
处理程序中的函数返回一个值,promise 使用该值解析/拒绝,如果函数返回一个promise,会发生什么,下一个then
子句将是promise的then
子句函数返回,因此,在这种情况下,第一个示例通过thens
的正常序列并打印出人们可能期望的值,在第二个示例中,当您执行Promise.resolve("bbb")
的 then 是在链接时调用的then
(对于所有意图和目的)。 The way it actually works is described below in more detail.下面更详细地描述了它的实际工作方式。
Quoting from the Promises/A+ spec:引用 Promises/A+ 规范:
The promise resolution procedure is an abstract operation taking as input a promise and a value, which we denote as
[[Resolve]](promise, x)
.承诺解析过程是一个抽象操作,将承诺和值作为输入,我们将其表示为
[[Resolve]](promise, x)
。 Ifx
is a thenable, it attempts to make promise adopt the state ofx
, under the assumption that x behaves at least somewhat like a promise .如果
x
是一个 thenable ,它会尝试让 promise采用x
的状态,假设 x 的行为至少有点像 promise 。 Otherwise, it fulfills promise with the valuex
.否则,它将以值
x
履行承诺。This treatment of thenables allows promise implementations to interoperate, as long as they expose a Promises/A+-compliant then method.
这种对 thenables 的处理允许 promise 实现互操作,只要它们公开一个符合 Promises/A+ 的 then 方法。 It also allows Promises/A+ implementations to “assimilate” nonconformant implementations with reasonable then methods.
它还允许 Promises/A+ 实现用合理的 then 方法“同化”不一致的实现。
The key thing to notice here is this line:这里要注意的关键是这一行:
if
x
is a promise, adopt its state [3.4]如果
x
是承诺,则采用其状态[3.4]link: https://promisesaplus.com/#point-49
链接: https : //promisesaplus.com/#point-49
Both of your examples should behave pretty much the same.您的两个示例的行为应该几乎相同。
A value returned inside a then()
handler becomes the resolution value of the promise returned from that then()
.在
then()
处理程序中返回的值成为从then()
返回的承诺的解析值。 If the value returned inside the .then
is a promise, the promise returned by then()
will "adopt the state" of that promise and resolve/reject just as the returned promise does.如果
.then
返回的值是一个承诺, then()
返回的承诺将“采用该承诺的状态”并像返回的承诺一样解决/拒绝。
In your first example, you return "bbb"
in the first then()
handler, so "bbb"
is passed into the next then()
handler.在您的第一个示例中,您在第一个
then()
处理程序中返回"bbb"
,因此将"bbb"
传递给下一个then()
处理程序。
In your second example, you return a promise that is immediately resolved with the value "bbb"
, so "bbb"
is passed into the next then()
handler.在您的第二个示例中,您返回一个立即使用值
"bbb"
解析的承诺,因此将"bbb"
传递给下一个then()
处理程序。 (The Promise.resolve()
here is extraneous). (这里的
Promise.resolve()
是无关紧要的)。
The outcome is the same.结果是一样的。
If you can show us an example that actually exhibits different behavior, we can tell you why that is happening.如果您可以向我们展示一个实际表现出不同行为的示例,我们就可以告诉您为什么会发生这种情况。
You already got a good formal answer.你已经得到了一个很好的正式答案。 I figured I should add a short one.
我想我应该添加一个简短的。
The following things are identical with Promises/A+ promises:以下内容与Promises/A+承诺相同:
Promise.resolve
(In your Angular case that's $q.when
)Promise.resolve
(在你的 Angular 情况下是$q.when
)new $q
.new $q
。then
callback.then
回调中返回一个值。 So the following are all identical for a promise or plain value X:因此,对于承诺或普通值 X,以下内容都是相同的:
Promise.resolve(x);
new Promise(function(resolve, reject){ resolve(x); });
Promise.resolve().then(function(){ return x; });
Promise.all([x]).then(function(arr){ return arr[0]; });
And it's no surprise, the promises specification is based on the Promise Resolution Procedure which enables easy interoperation between libraries (like $q and native promises) and makes your life overall easier.毫不奇怪,promise 规范基于Promise 解析过程,它可以实现库之间的轻松互操作(如 $q 和本机承诺),并使您的生活整体更轻松。 Whenever a promise resolution might occur a resolution occurs creating overall consistency.
每当可能发生承诺解决方案时,就会发生解决方案,从而创建整体一致性。
The only difference is that you're creating an unnecessary promise when you do return Promise.resolve("bbb")
.唯一的区别是,当您
return Promise.resolve("bbb")
时,您正在创建一个不必要的承诺。 Returning a promise from an onFulfilled()
handler kicks off promise resolution .从
onFulfilled()
处理程序返回承诺会启动 承诺解析。 That's how promise chaining works.这就是承诺链的工作原理。
Just a point.只是一点。 The 'resolve' function does not return as you can see in a debugger.
正如您在调试器中看到的那样,“解决” function 不会返回。 It seems to return if it is the last statement.
如果它是最后一个语句,它似乎会返回。 'Resolve' will set the promise as fullfilled but continue execution if there are more statements below.
“解决”会将 promise 设置为已满,但如果下面有更多语句,则继续执行。
As you can read here: 'Why does javascript ES6 Promises continue execution after a resolve?'正如您可以在此处阅读的: “为什么 javascript ES6 Promise 在解析后继续执行?”
This was very confusing for me because it is not explained in most examples.这让我很困惑,因为大多数例子都没有解释。 So from now on, I have to remember to use 'return resolve(value)' or an 'if resolve(value) else...other code' or just use 'resolve' as the last statement.
所以从现在开始,我必须记住使用“return resolve(value)”或“if resolve(value) else...other code”,或者只使用“resolve”作为最后一个语句。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.