返回值和承诺之间的区别是什么?从那时开始解决()

有什么区别:

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

这:

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

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

281791 次浏览

这两个例子的行为应该是一样的。

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

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

在第二个示例中,返回一个承诺,该承诺立即用值"bbb"解析,因此"bbb"被传递给下一个then()处理程序。(这里的Promise.resolve()是无关的)。

结果是一样的。

如果你能给我们举个例子,它能表现出不同的行为,我们就能告诉你为什么会这样。

规则是,如果then处理程序中的函数返回一个值,promise将使用该值进行解析/拒绝,如果函数返回一个promise,所发生的是,下一个then子句将是函数返回的承诺then子句,因此,在这种情况下,第一个示例通过thens的正常序列,并像人们预期的那样打印出值,在第二个示例中,当你执行Promise.resolve("bbb")时返回的promise对象是在链接时被调用的then(出于所有意图和目的)。下面将更详细地描述它的实际工作方式。

引用承诺/A+规范:

承诺解析过程是一个抽象操作,将一个承诺和一个值作为输入,我们将其标记为[[Resolve]](promise, x)如果x是一个thenable,它尝试使promise 采用x的状态,假设x的行为至少有点像一个promise。否则,它用值x履行promise。

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

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

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

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

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

以下内容与承诺/ +承诺相同:

  • 调用Promise.resolve(在Angular中是$q.when)
  • 调用承诺构造函数并在其解析器中解析。在你的例子中是new $q
  • then回调返回一个值。
  • 要求的承诺。都在一个有值的数组上,然后提取那个值。

因此,对于承诺值或普通值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]; });

毫无疑问,promises规范是基于承诺解决程序的,它使得库之间(如$q和本机promises)的互操作变得简单,并使你的生活总体上更简单。无论何时出现承诺解决方案,解决方案都会产生整体一致性。

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

A)当x是一个值(数字,字符串等):

  1. return x等价于return Promise.resolve(x)
  2. throw x等价于return Promise.reject(x)

B)当x是一个已经解决(不再待定)的Promise时:

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

C)当x是一个待定的Promise时:

  1. return x将返回一个悬而未决的Promise,它将在后续的then上求值。

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

唯一的区别是,当你执行return Promise.resolve("bbb")时,你创建了一个不必要的承诺。从onFulfilled()处理程序返回一个promise将启动承诺解决。这就是承诺链接的工作方式。

只是一点。在调试器中,'resolve'函数不会返回。如果是最后一个语句,则返回。'Resolve'将把承诺设置为已完成,但如果下面有更多语句,则继续执行。

你可以在这里读到:“为什么javascript ES6承诺在解决后继续执行?”

这让我很困惑,因为在大多数例子中都没有解释。所以从现在开始,我必须记住使用'return resolve(value)'或'if resolve(value) else…其他代码'或只是使用'resolve'作为最后的语句。