本文翻译自: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"; }) .then(function(result) { console.log(result); });
and this: 还有这个:
new Promise(function(res, rej) { res("aaa"); }) .then(function(result) { return Promise.resolve("bbb"); }) .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服务与链接.then()有不同的行为。 A bit too much code hence first the example above. 有点太多的代码因此首先是上面的例子。
#1楼
参考:https://stackoom.com/question/1Si0z/从那时起返回值或Promise-resolve有什么区别
#2楼
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()
返回的promise的解析值。 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
返回的值是一个promise, then()
返回的promise将“采用该promise的状态”并像返回的promise一样解析/拒绝。
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"
立即解析的promise,因此将"bbb"
传递给next 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. 如果您能向我们展示一个实际表现出不同行为的示例,我们可以告诉您为什么会发生这种情况。
#3楼
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
处理返回一个值,承诺解决与价值/拒绝,如果该函数返回一个承诺,会发生什么情况是,接下来then
条款将是then
的承诺条款函数返回 ,因此,在这种情况下,第一个示例通过thens
的正常序列,并打印出值,如第二个示例中所示,当您执行Promise.resolve("bbb")
时返回的promise对象Promise.resolve("bbb")
的则是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)
. promise解析过程是一个抽象操作,它将promise和value作为输入,我们将其表示为[[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
是一个可能的,它会尝试使x
采用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 +的方法即可。 It also allows Promises/A+ implementations to “assimilate” nonconformant implementations with reasonable then methods. 它还允许Promises / A +实现使用合理的方法“同化”不一致的实现。
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
#4楼
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 +承诺相同:
- Calling
Promise.resolve
(In your Angular case that's$q.when
) 调用Promise.resolve
(在你的Angular案例中是$q.when
) - Calling the promise constructor and resolving in its resolver. 调用promise构造函数并在其解析器中解析。 In your case that's
new $q
. 在你的情况下,这是new $q
。 - Returning a value from a
then
callback. 从then
回调中返回一个值。 - Calling Promise.all on an array with a value and then extract that value. 在具有值的数组上调用Promise.all,然后提取该值。
So the following are all identical for a promise or plain value X: 所以以下对于promise或普通值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. 并且毫不奇怪,Promises规范基于Promise Resolution Procedure ,它可以实现库之间的轻松互操作(如$ q和本机承诺),让您的生活更加轻松。 Whenever a promise resolution might occur a resolution occurs creating overall consistency. 只要可能发生承诺解决,就会出现解决方案,从而产生整体一致
#5楼
In simple terms, inside a then
handler function: 简单来说,在一个then
处理函数里面:
A) When x
is a value (number, string, etc): A)当x
是一个值(数字,字符串等)时:
-
return x
is equivalent toreturn Promise.resolve(x)
return x
相当于return Promise.resolve(x)
-
throw x
is equivalent toreturn Promise.reject(x)
throw x
相当于return Promise.reject(x)
B) When x
is a Promise that is already settled (not pending anymore): B)当x
是已经结算的承诺(不再等待)时:
-
return x
is equivalent toreturn Promise.resolve(x)
, if the Promise was already resolved. 如果Promise已经解决,则return x
等效于return Promise.resolve(x)
。 -
return x
is equivalent toreturn Promise.reject(x)
, if the Promise was already rejected. 如果Promise已被拒绝,则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 subsequentthen
.return x
将返回一个未决无极,它会在随后进行评价then
。
Read more on this topic on the Promise.prototype.then() docs . 在Promise.prototype.then()文档中阅读有关此主题的更多信息。