【问题标题】:Why are consequent chained promises resolved?为什么后续的链式 Promise 会被解决?
【发布时间】:2015-03-30 14:34:52
【问题描述】:

我试图理解 Promises/A+,但我对几点感到困惑。考虑一下:

function foo() {
    console.log("In 'foo' function: --> which returns a Promise");
    return new Promise(function (resolve, reject) {
        resolve()
    });
}

var promise1 = foo();

var promise2 = promise1.then(function () {
    console.log("Promise 1 has been resolved --> onFulfilled() returns a value");
    return 1;
});

var promise3 = promise2.then(function () {
    console.log("Promise 2 has been resolved --> onFulfilled() is not returning anything from inFulfilled()");
});

var promise4 = promise3.then(function () {
    console.log("Promise 3 has been resolved");
});

/* Console:
In 'foo' function: --> which returns a Promise
Promise 1 has been resolved --> onFulfilled() returns a value
Promise 2 has been resolved --> onFulfilled() is not returning anything from inFulfilled()
Promise 3 has been resolved
*/
  • 必须通过调用resolve() 显式解决Promise 1,否则执行会停止。为什么使用 Promise 2 和 3 时,执行会认为这些已解决(不需要 resolve())并进入链中的下一个 .then
  • 链接到 promise2 的“onFullfilled()”函数不返回值。我在规范中找不到任何明确的reference 在这种情况下应该发生什么。这种情况是否被视为函数返回undefined?这取决于所使用库的实际实现吗?

【问题讨论】:

  • 在 JavaScript 中不返回任何内容与 return undefined 相同,这意味着您使用 undefined 解决了承诺。调用者无法区分忘记返回和显式 return undefined 之间的区别,因此它不是实现。如果可以,那就太好了,因为忘记返回语句是最常见的承诺错误。

标签: javascript node.js promise bluebird


【解决方案1】:

Promise 处理程序(成功或错误处理程序)具有返回值。每个 then 调用都会创建一个新的 Promise。

如果返回一个值,则承诺会自动解析。如果返回另一个 Promise,则 Promise 将等待直到它被解决或被拒绝,然后再继续 Promise 链中的下一个 then 调用。

我认为这解释了您所看到的行为。

【讨论】:

    【解决方案2】:

    您正在寻找的行为在 promise/A+ 规范中的 #7 (https://github.com/promises-aplus/promises-spec#the-then-method)。

    promise2 = promise1.then(onFulfilled, onRejected);

    "如果 onFulfilled 或 onRejected 返回值 x,则运行 Promise Resolution Procedure [[Resolve]](promise2, x)。"

    我从中得出的结论是,当第一个 Promise 失败/解决时,由它创建的任何 Promise(包括新的 Promise promise2)都会失败/解决。

    例如:当您在示例中解析 promise1 时,所有后续承诺也会解析。

    【讨论】:

      【解决方案3】:

      我对您的代码做了一些小调整:

      • 将参数传递给resolve(data),例如resolve(1001)
      • .then中检索并显示数据
      • 同样在.then 中用return new Promise 返回链中的下一个Promise

      这是你的示例重新设计:

      var promise1 = new Promise(function (resolve, reject) {
          console.log("Creating Promise 1");
          resolve( 1001 );
      } );
      
      var promise2 = promise1.then(function (data1) {
          console.log("Promise 1 has been resolved --> ", data1);
          return new Promise(function (resolve, reject) {
              console.log("Creating Promise 2");
              resolve( 1002 );
          } );
      } );
      
      var promise3 = promise2.then(function (data2) {
          console.log("Promise 2 has been resolved --> ", data2);
          return new Promise(function (resolve, reject) {
              console.log("Creating Promise 3");
              resolve( 1003 );
          } );
      } );
      
      promise3.then(function (data3) {
          console.log("Promise 3 has been resolved --> ", data3);
      } );

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-09-12
        • 2019-03-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多