从那时起返回值或Promise.resolve有什么区别()

spi*_*tus 294 javascript promise angularjs q

有什么区别:

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

还有这个:

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

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

Hri*_*shi 129

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

引用Promises/A +规范:

promise解析过程是一个抽象操作,它将promise和value作为输入,我们将其表示为[[Resolve]](promise, x).如果x是一个卑鄙的,它会尝试在x假设至少有点像承诺的情况下承诺采用状态x.否则,它履行了价值的承诺x.

对thenables的这种处理允许promise实现进行互操作,只要它们公开符合Promises/A +的方法即可.它还允许Promises/A +实现使用合理的方法"同化"不一致的实现.

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

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

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

  • 实际上 - 这里规范的相关部分是`[[Resolve]]`在`then`ables和values都被调用的事实,所以基本上它包含一个带有promise的值,所以`return"aaa"`就像`return Promise.resolve("aaa")`和`return Promise.resolve("aaa")`与`return Promise.resolve(Promise.resolve("aaa"))`相同` - 因为resolve是幂等函数调用它不止一次的值具有相同的结果. (64认同)
  • 是的,这正是它的意思. (9认同)
  • @Benjamin Gruenbaum是否意味着返回`"aaa"`和`返回Promise.resolve("aaa")`在任何情况下都可以在`then`ables中互换? (8认同)
  • 当"then"处理程序返回一个promise时,"Adopt its state"是一种表达行为的简洁而有用的方法.+1规范参考. (3认同)

JLR*_*she 90

你的两个例子都应该表现得非常相似.

then()处理程序内返回的值将成为从该返回的promise的解析值then().如果在.then promise中返回的值是promise,则返回的promise then()将"采用该promise的状态"并解析/拒绝,就像返回的promise一样.

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

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

结果是一样的.

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

  • @FabianTe 这些也有相同的效果,除了用 `undefined` 代替 `"bbb"`。 (2认同)

Ari*_*sta 88

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

A)什么时候x是一个值(数字,字符串等):

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

B)什么x是已经结算的承诺(不再等待):

  1. return xreturn Promise.resolve(x)如果承诺已经解决,则相当于.
  2. return xreturn Promise.reject(x)如果承诺已被拒绝,则相当于.

C)什么x是未决的承诺:

  1. return x将返回一个待处理的Promise,并将在后续评估then.

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

  • @Lancer.Yan 不是真的,B 表示的是 `return` 的行为根据 Promise 的确定值而变化。当编写代码时,您并不真正知道它是否会解决或拒绝。当然,您可以使用 try-catch 来处理拒绝,然后重新抛出,但这是不同的情况。 (2认同)

Ben*_*aum 49

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

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

  • 打电话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]; });
Run Code Online (Sandbox Code Playgroud)

并且毫不奇怪,Promises规范基于Promise Resolution Procedure,它可以实现库之间的轻松互操作(如$ q和本机承诺),让您的生活更轻松.只要可能发生承诺解决,就会出现解决方案,从而产生整体一致