简体   繁体   English

then() 返回值或 Promise.resolve 之间有什么区别

[英]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是一个值(数字、字符串等)时:

  1. return x is equivalent to return Promise.resolve(x) return x等价于return Promise.resolve(x)
  2. 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 时:

  1. return x is equivalent to return Promise.resolve(x) , if the Promise was already resolved. return x等价于return Promise.resolve(x) ,如果 Promise 已经解决了。
  2. return x is equivalent to return 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 时:

  1. 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子句将是promisethen子句函数返回,因此,在这种情况下,第一个示例通过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) If x is a thenable, it attempts to make promise adopt the state of x , under the assumption that x behaves at least somewhat like a promise .如果x是一个 thenable ,它会尝试让 promise采用x的状态,假设 x 的行为至少有点像 promise Otherwise, it fulfills promise with the value x .否则,它将以值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+承诺相同:

  • 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:因此,对于承诺或普通值 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.

相关问题 返回值和从函数返回 Promise.resolve() 的区别 - Difference between returning a value and returning Promise.resolve() from a function 返回新的 Promise 和 Promise.resolve 之间的区别 - Difference between returning new Promise and Promise.resolve Promise.resolve()和resolve()之间的区别? - Difference between Promise.resolve() and just resolve()? Promise.resolve(可用)和新Promise(thenable.then)有什么区别? - What is the difference between Promise.resolve(thenable) and new Promise(thenable.then)? Promise.resolve 和空 Promise Object 的区别 - Difference between Promise.resolve and empty Promise Object 艰难地理解Promise.resolve()和Promise链之间的区别 - Hard time understanding difference between Promise.resolve() and promise chain 蓝鸟中新Promise和Promise.resolve / reject之间的区别 - Difference between new Promise and Promise.resolve/reject in bluebird 异步函数中的return undefined和return Promise.resolve()有什么区别? - What's the differences between return undefined & return Promise.resolve() in async function? JS:Promise.resolve() 的用例是什么 - JS: what's a use-case of Promise.resolve() 当我们在微任务队列中返回一个值并从 then() 链返回一个 Promise.resolve 时会发生什么? - What happen when we return a value and when we return a Promise.resolve from a then() chain, in the microtask queue?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM