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

IT技术 javascript angularjs promise q
2021-02-08 11:42:37

有什么区别:

new Promise(function(res, rej) {
    res("aaa");
  })
  .then(function(result) {
    return "bbb";
  })
  .then(function(result) {
    console.log(result);
  });

还有这个:

new Promise(function(res, rej) {
    res("aaa");
  })
  .then(function(result) {
    return Promise.resolve("bbb");
  })
  .then(function(result) {
    console.log(result);
  });

我问是因为我得到了不同的行为使用 Angular 和 $http 服务与链接 .then()。代码有点多,因此首先是上面的示例。

5个回答

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

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

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

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

  1. return x等价于return Promise.resolve(x), 如果 Promise 已经解决。
  2. return x等价于return Promise.reject(x), 如果 Promise 已经被拒绝。

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

  1. return x将返回一个挂起的 Promise,并将在随后的then.

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

@Lancer.Yan 不是真的,B 表示的是行为的return变化取决于 Promise 的固定值。在编写代码时,您真的不知道它会解决还是拒绝。当然,您可以使用 try-catch 来处理拒绝然后重新抛出,但这是一个不同的场景。
2021-03-19 11:42:37
【B) 2.】应该是“扔x”吗?
2021-03-20 11:42:37

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

引用 Promises/A+ 规范:

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

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

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

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

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

其实-这里的规范相关的部分是事实,[[Resolve]]被称为上都thenABLES和值,所以本质上它包装与Promise不符的值,因此return "aaa"是一样的return Promise.resolve("aaa"),并return Promise.resolve("aaa")是一样的return Promise.resolve(Promise.resolve("aaa"))-因为决心是幂等调用它的值更不止一次有相同的结果。
2021-03-15 11:42:37
“如果 then 处理程序中的函数返回一个值,则Promise将使用该值解决/拒绝,”我认为答案应该阐明Promise何时解决以及何时拒绝,而不是说“Promise解决/拒绝”。
2021-03-18 11:42:37
@Benjamin Gruenbaum 这是否意味着在任何情况下都可以返回"aaa"并且return Promise.resolve("aaa")可以互换then
2021-03-28 11:42:37
是的,这正是它的意思。
2021-03-30 11:42:37
“采用其状态”是一种简洁而有用的方式来表达then处理程序返回Promise时的行为+1 用于规范参考。
2021-04-05 11:42:37

您的两个示例的行为应该几乎相同。

then()处理程序内返回的值成为从处理程序返回的Promise的解析值then()如果返回的值.then 是一个promise,则返回的promisethen()将“采用该promise 的状态”并像返回的promise 一样解决/拒绝。

在您的第一个示例中,您"bbb"在第一个then()处理程序中返回,因此"bbb"被传递到下一个then()处理程序。

在您的第二个示例中,您返回一个立即使用 value 解析的Promise"bbb",因此"bbb"将其传递给下一个then()处理程序。Promise.resolve()这里是无关紧要的)。

结果是一样的。

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

@FabianTe 那些也有同样的效果,除了undefined代替"bbb"
2021-03-25 11:42:37
不错的答案!怎么样Promise.resolve();VS return;
2021-04-04 11:42:37

你已经得到了一个很好的正式答案。我想我应该添加一个简短的。

以下内容与Promises/A+Promise相同

  • 调用Promise.resolve(在你的 Angular 情况下是$q.when
  • 调用 promise 构造函数并在其解析器中解析。在你的情况下,这是new $q.
  • then回调中返回一个值
  • 对具有值的数组调用 Promise.all,然后提取该值。

因此,对于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]; });

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

它在所有同步代码发生之后但在任何 I/O 发生之前异步执行调用。这就是所谓的“microtick 语义”。
2021-03-13 11:42:37
请问这样做有什么意义Promise.resolve().then(function(){ return x; });我发现了一个做类似事情的then片段(它在内调用了一个函数)。我认为这或多或少像做一个超时,但它有点快。jsben.ch/HIfDo
2021-03-14 11:42:37
在 99.99% 的情况下,它与 Promise.resolve(x) 相同是没有意义的。(0.001% 是我们在一个with对象或代理上的块中,带有x抛出异常属性访问器。在这种情况下, Promise.resolve(x) 将导致抛出错误,但Promise.resolve().then(function(){ return x; });由于抛出错误,因此将被拒绝Promise在一个then)。
2021-03-24 11:42:37
你链接了一个空的闪电战,或者你没有保存。无论如何,我不是在谈论陈述之间的差异。我说的正是我写的东西。为了更清楚,这是我正在谈论的片段:if (validator) { Promise.resolve().then(() => { this._cdRef.markForCheck(); }); }. 这里没有分配Promise,那有什么意义呢?超时是否会(或多或少)产生相同的效果?
2021-03-29 11:42:37

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