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(). A bit too much code hence first the example above.
我问的是,我使用的是角和$http服务的不同行为。代码太多了,所以第一个例子就是上面的例子。
4 个解决方案
#1
96
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). The way it actually works is described below in more detail.
规则是,如果函数在处理程序返回一个值,承诺解决/拒绝与该值,如果函数返回一个承诺,将会发生什么,未来将当时的条款的承诺返回的函数,所以,在这种情况下,第一个例子失败然后和输出值的正常序列正如你所预料的那样,在第二个示例中,当您执行Promise.resolve .resolve(“bbb”)的时候,这个承诺对象就会被调用,然后在链接(所有意图和目的)时被调用。下面详细描述了它的实际工作方式。
Quoting from the Promises/A+ spec:
引用承诺/A+规范:
The promise resolution procedure is an abstract operation taking as input a promise and a value, which we denote as
[[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. Otherwise, it fulfills promise with the valuex
.承诺解决程序是一个抽象的操作,作为输入一个承诺和一个值,我们将其表示为[[Resolve]](promise, x)。如果x是一个thenable,它试图使promise采用x的状态,假设x的行为至少有点像一个承诺。否则,它将实现对值x的承诺。
This treatment of thenables allows promise implementations to interoperate, as long as they expose a Promises/A+-compliant then method. It also allows Promises/A+ implementations to “assimilate” nonconformant implementations with reasonable then methods.
这种方法允许承诺实现互操作,只要它们公开了一个承诺/一个兼容的方法。它还允许承诺/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
#2
62
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()
. 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()处理程序中返回的值将成为从那个()返回的承诺的解析值。如果返回的值是一个承诺,那么这个承诺返回的承诺将“采纳”承诺的状态,并像返回的承诺一样解决/拒绝。
In your first example, you return "bbb"
in the first then()
handler, so "bbb"
is passed into the next then()
handler.
在您的第一个示例中,在第一个then()处理程序中返回“bbb”,因此“bbb”被传递到下一个()处理程序。
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. (The Promise.resolve()
here is extraneous).
在您的第二个示例中,您返回一个承诺,该承诺立即以“bbb”的值解析,因此“bbb”将传递到下一个()处理程序。(承诺)这里是无关紧要的。
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
36
You already got a good formal answer. I figured I should add a short one.
你已经得到了一个很好的正式答复。我想我应该加上一个短的。
The following things are identical with Promises/A+ promises:
以下内容与承诺/承诺:
- Calling
Promise.resolve
(In your Angular case that's$q.when
) - 要求的承诺。解决(在你的角度的情况下,这是$ qwhen)
- Calling the promise constructor and resolving in its resolver. In your case that's
new $q
. - 调用承诺构造函数并解析它的解析器。在你的情况下,这是新的$q。
- Returning a value from a
then
callback. - 从然后回调返回一个值。
- Calling Promise.all on an array with a value and then extract that value.
- 要求的承诺。所有的数组都具有一个值,然后提取该值。
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. Whenever a promise resolution might occur a resolution occurs creating overall consistency.
这并不奇怪,承诺规范是基于承诺解决程序的,它使得库之间容易的互操作(如$q和本地承诺),使您的生活更容易。当一个承诺解决方案可能出现时,一个解决方案就会产生整体的一致性。
#4
17
In simple terms, inside a then
handler function:
简单地说,在一个then handler函数中:
A) When x
is a value (number, string, etc):
A)当x为值时(数字、字符串等):
-
return x
is equivalent toreturn Promise.resolve(x)
- 返回x等于返回Promise.resolve(x)
-
throw x
is equivalent toreturn Promise.reject(x)
- 抛出x等于返回承诺。拒绝(x)
B) When x
is a Promise that is already settled (not pending anymore):
当x是一个已经确定的承诺(不再等待):
-
return x
is equivalent toreturn Promise.resolve(x)
, if the Promise was already resolved. - 返回x相当于返回Promise.resolve(x),如果这个承诺已经解决了。
-
return x
is equivalent toreturn Promise.reject(x)
, if the Promise was already rejected. - 返回x等于返回承诺。拒绝(x),如果承诺已经被拒绝。
C) When x
is a Promise that is pending:
C)当x是一个未决的承诺:
-
return x
will return a pending Promise, and it will be evaluated on the subsequentthen
. - return x将返回一个未完成的承诺,并将在其后进行评估。
Read more on this topic on the Promise.prototype.then() docs.
在promise.prototypethen()文档中阅读更多关于这个主题的内容。
#1
96
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). The way it actually works is described below in more detail.
规则是,如果函数在处理程序返回一个值,承诺解决/拒绝与该值,如果函数返回一个承诺,将会发生什么,未来将当时的条款的承诺返回的函数,所以,在这种情况下,第一个例子失败然后和输出值的正常序列正如你所预料的那样,在第二个示例中,当您执行Promise.resolve .resolve(“bbb”)的时候,这个承诺对象就会被调用,然后在链接(所有意图和目的)时被调用。下面详细描述了它的实际工作方式。
Quoting from the Promises/A+ spec:
引用承诺/A+规范:
The promise resolution procedure is an abstract operation taking as input a promise and a value, which we denote as
[[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. Otherwise, it fulfills promise with the valuex
.承诺解决程序是一个抽象的操作,作为输入一个承诺和一个值,我们将其表示为[[Resolve]](promise, x)。如果x是一个thenable,它试图使promise采用x的状态,假设x的行为至少有点像一个承诺。否则,它将实现对值x的承诺。
This treatment of thenables allows promise implementations to interoperate, as long as they expose a Promises/A+-compliant then method. It also allows Promises/A+ implementations to “assimilate” nonconformant implementations with reasonable then methods.
这种方法允许承诺实现互操作,只要它们公开了一个承诺/一个兼容的方法。它还允许承诺/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
#2
62
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()
. 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()处理程序中返回的值将成为从那个()返回的承诺的解析值。如果返回的值是一个承诺,那么这个承诺返回的承诺将“采纳”承诺的状态,并像返回的承诺一样解决/拒绝。
In your first example, you return "bbb"
in the first then()
handler, so "bbb"
is passed into the next then()
handler.
在您的第一个示例中,在第一个then()处理程序中返回“bbb”,因此“bbb”被传递到下一个()处理程序。
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. (The Promise.resolve()
here is extraneous).
在您的第二个示例中,您返回一个承诺,该承诺立即以“bbb”的值解析,因此“bbb”将传递到下一个()处理程序。(承诺)这里是无关紧要的。
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
36
You already got a good formal answer. I figured I should add a short one.
你已经得到了一个很好的正式答复。我想我应该加上一个短的。
The following things are identical with Promises/A+ promises:
以下内容与承诺/承诺:
- Calling
Promise.resolve
(In your Angular case that's$q.when
) - 要求的承诺。解决(在你的角度的情况下,这是$ qwhen)
- Calling the promise constructor and resolving in its resolver. In your case that's
new $q
. - 调用承诺构造函数并解析它的解析器。在你的情况下,这是新的$q。
- Returning a value from a
then
callback. - 从然后回调返回一个值。
- Calling Promise.all on an array with a value and then extract that value.
- 要求的承诺。所有的数组都具有一个值,然后提取该值。
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. Whenever a promise resolution might occur a resolution occurs creating overall consistency.
这并不奇怪,承诺规范是基于承诺解决程序的,它使得库之间容易的互操作(如$q和本地承诺),使您的生活更容易。当一个承诺解决方案可能出现时,一个解决方案就会产生整体的一致性。
#4
17
In simple terms, inside a then
handler function:
简单地说,在一个then handler函数中:
A) When x
is a value (number, string, etc):
A)当x为值时(数字、字符串等):
-
return x
is equivalent toreturn Promise.resolve(x)
- 返回x等于返回Promise.resolve(x)
-
throw x
is equivalent toreturn Promise.reject(x)
- 抛出x等于返回承诺。拒绝(x)
B) When x
is a Promise that is already settled (not pending anymore):
当x是一个已经确定的承诺(不再等待):
-
return x
is equivalent toreturn Promise.resolve(x)
, if the Promise was already resolved. - 返回x相当于返回Promise.resolve(x),如果这个承诺已经解决了。
-
return x
is equivalent toreturn Promise.reject(x)
, if the Promise was already rejected. - 返回x等于返回承诺。拒绝(x),如果承诺已经被拒绝。
C) When x
is a Promise that is pending:
C)当x是一个未决的承诺:
-
return x
will return a pending Promise, and it will be evaluated on the subsequentthen
. - return x将返回一个未完成的承诺,并将在其后进行评估。
Read more on this topic on the Promise.prototype.then() docs.
在promise.prototypethen()文档中阅读更多关于这个主题的内容。