关于javascript:从那时返回值或Promise.resolve有什么区别()

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

有什么区别:

1
2
3
4
5
6
7
8
9
new Promise(function(res, rej) {
    res("aaa");
  })
  .then(function(result) {
    return"bbb";
  })
  .then(function(result) {
    console.log(result);
  });

还有这个:

1
2
3
4
5
6
7
8
9
new Promise(function(res, rej) {
    res("aaa");
  })
  .then(function(result) {
    return Promise.resolve("bbb");
  })
  .then(function(result) {
    console.log(result);
  });

我问的是,使用Angular和$HTTP服务进行链接时,我得到了不同的行为。代码有点太多,因此首先是上面的示例。


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

引用承诺/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 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. 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.

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

if x is a promise, adopt its state [3.4]

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


你的两个例子应该表现得差不多。

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

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

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

结果是一样的。

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


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

a)当x是一个值(数字、字符串等)时:

  • return x相当于return Promise.resolve(x)
  • throw x相当于return Promise.reject(x)
  • b)当x是一个已经解决(不再待定)的承诺时:

  • 如果承诺已经得到解决,那么return x相当于return Promise.resolve(x)
  • 如果承诺已经被拒绝,那么return x等同于return Promise.reject(x)
  • c)当x是一个待决的承诺时:

  • return x将返回一个待定的承诺,并将在随后的then上进行评估。
  • 阅读promise.prototype.then()文档中有关此主题的更多信息。


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

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

    • 打电话给Promise.resolve(在角度的情况下,是$q.when)
    • 调用Promise构造函数并在其冲突解决程序中解析。在你的例子中,那是new $q
    • then回调返回值。
    • 在带有值的数组中调用promise.all,然后提取该值。

    因此,对于承诺值或普通值x,以下内容完全相同:

    1
    2
    3
    4
    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规范基于Promises解析过程,该过程使库(如$Q和本机Promises)之间的互操作变得容易,并使您的总体生活更加轻松。每当可能出现承诺解决方案时,都会出现解决方案,从而创建整体一致性。