Javascript 从 then() 返回值或 Promise.resolve 有什么区别

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/27715275/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 00:32:54  来源:igfitidea点击:

What's the difference between returning value or Promise.resolve from then()

javascriptangularjspromiseq

提问by spirytus

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.

我问是因为我得到了不同的行为 Using Angular and $http service with chaining .then()。代码有点多,因此首先是上面的示例。

回答by Hrishi

The rule is, if the function that is in the thenhandler returns a value, the promise resolves/rejects with that value, and if the function returns a promise, what happens is, the next thenclause will be the thenclause of the promise the function returned, so, in this case, the first example falls through the normal sequence of the thensand 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 thenthat gets invoked when chaining(for all intents and purposes). The way it actually works is described below in more detail.

规则是,如果then处理程序中的函数返回一个值,promise 用该值解析/拒绝,如果函数返回一个promise,会发生什么,下一个then子句将是函数返回的promise 的then子句,因此,在这种情况下,第一个示例不符合 the 的正常序列并按预期打印出值,在第二个示例中,在执行's then时返回的 promise 对象是在链接时调用的(出于所有意图和目的)。下面更详细地描述了它的实际工作方式。thensPromise.resolve("bbb")then

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). If xis a thenable, it attempts to make promise adopt the state of x, under the assumption that x behaves at least somewhat like a promise. Otherwise, it fulfills promise with the value 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.

承诺解析过程是一个抽象操作,将承诺和值作为输入,我们将其表示为[[Resolve]](promise, x)Ifx是 thenable,它试图让 promise采用 的状态x,假设 x 的行为至少有点像 promise。否则,它将以 value 履行承诺x

对 thenables 的这种处理允许 promise 实现互操作,只要它们公开一个符合 Promises/A+ 的 then 方法。它还允许 Promises/A+ 实现使用合理的 then 方法“同化”不一致的实现。

The key thing to notice here is this line:

这里要注意的关键是这一行:

if xis a promise, adopt its state[3.4]

link: https://promisesaplus.com/#point-49

如果x是承诺,则采用其状态[3.4]

链接:https: //promisesaplus.com/#point-49

回答by Arian Acosta

In simple terms, inside a thenhandler function:

简单来说,在then处理函数内部:

A) When xis a value (number, string, etc):

A) Whenx是一个值(数字、字符串等):

  1. return xis equivalent to return Promise.resolve(x)
  2. throw xis equivalent to return Promise.reject(x)
  1. return x相当于 return Promise.resolve(x)
  2. throw x相当于 return Promise.reject(x)

B) When xis a Promise that is already settled (not pending anymore):

B) 什么时候x一个 Promise 已经被解决(不再挂起):

  1. return xis equivalent to return Promise.resolve(x), if the Promise was already resolved.
  2. return xis equivalent to return Promise.reject(x), if the Promise was already rejected.
  1. return x等价于return Promise.resolve(x), 如果 Promise 已经解决。
  2. return x等价于return Promise.reject(x), 如果 Promise 已经被拒绝。

C) When xis a Promise that is pending:

C) 何时x有待处理的 Promise:

  1. return xwill return a pending Promise, and it will be evaluated on the subsequent then.
  1. return x将返回一个挂起的 Promise,并将在随后的then.

Read more on this topic on the Promise.prototype.then() docs.

Promise.prototype.then() 文档中阅读有关此主题的更多信息。

回答by JLRishe

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 .thenis 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()。如果返回的值.then是一个promise,则返回的promisethen()将“采用该promise 的状态”并像返回的promise 一样解决/拒绝。

In your first example, you return "bbb"in the first then()handler, so "bbb"is passed into the next then()handler.

在您的第一个示例中,您"bbb"在第一个then()处理程序中返回,因此"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. (The Promise.resolve()here is extraneous).

在您的第二个示例中,您返回一个立即使用 value 解析的承诺"bbb",因此"bbb"将其传递给下一个then()处理程序。(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.

如果您可以向我们展示一个实际表现出不同行为的示例,我们可以告诉您为什么会发生这种情况。

回答by Benjamin Gruenbaum

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)
  • Calling the promise constructor and resolving in its resolver. In your case that's new $q.
  • Returning a value from a thencallback.
  • Calling Promise.all on an array with a value and then extract that value.
  • 调用Promise.resolve(在你的 Angular 情况下是$q.when
  • 调用 promise 构造函数并在其解析器中解析。在你的情况下,这是new $q.
  • then回调中返回一个值。
  • 对具有值的数组调用 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 Procedurewhich 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.

毫不奇怪,promise 规范基于Promise 解析过程,它可以实现库之间的轻松互操作(如 $q 和本机 promises),并使您的生活更轻松。每当可能发生承诺解决方案时,就会发生解决方案,从而创建整体一致性。

回答by vkarpov15

The only difference is that you're creating an unnecessary promise when you do return Promise.resolve("bbb"). Returning a promise from an onFulfilled()handler kicks off promise resolution. That's how promise chainingworks.

唯一的区别是,当您这样做时,您正在创建一个不必要的承诺return Promise.resolve("bbb")。从onFulfilled()处理程序返回承诺将启动承诺解析。这就是承诺链的工作原理。