【问题标题】:Chaining promises doesn't pass data from one .then to the next链接承诺不会将数据从一个 .then 传递到下一个
【发布时间】:2020-01-06 20:12:21
【问题描述】:

我正在尝试在 mocha 测试中链接承诺,但似乎数据没有从一个 .then 传递到下一个。

我正在尝试测试一个可以更新数据库中一行的函数。然后我想查询该行以查看是否已应用更改。

我的测试:

    it("should update the status of an appointment", function(done) {
      new Promise((resolve, reject) => {
        updateStatus(testDb, 3, "In Progress", function(err) {
          if (err) reject(err);
          resolve();
        });
      })
        .then(() => {
          new Promise((resolve, reject) => {
            getOneAppointment(testDb, 3, function(err, appt) {
              if (err) reject(err);
              resolve(appt);
            });
          });
        })
        .then(appt => {
          console.log(appt);
          expect(appt).deep.equal(updatedResponse);
          done();
        })
        .catch(err => {
          done(err);
        });
    });

第二个.then 中的console.log 打印为未定义。

【问题讨论】:

  • 回报你的新承诺
  • 知道没有任何return 语句的函数有一个隐含 return undefined 很有用...知道箭头函数的简短版本也很有用例如...arg => blah() 等同于arg => { return blah();}...所以至少上面的一个地方可以删除一些{} 而不是添加return
  • @Trevor 可以,但你能解释一下为什么我不需要返回第一个承诺吗?
  • 理论上你应该把它归还给某物。使用 new 关键字而不将值存储到某些东西并不是很好。但是您的第一个承诺不会解析为一个值,因此返回它会给出未定义的结果,就像不返回它一样。作为一种习惯,对于任何没有真正返回值的承诺,我通常返回 true 表示成功,而返回 false 表示失败。

标签: javascript node.js asynchronous promise mocha.js


【解决方案1】:

如 cmets 中所述,您应该返回新的 Promise。下面是一个演示 Promise 链接的模拟示例:

new Promise( function (resolve, reject) {
    console.log("Should update the status of an appopintment");
    resolve( { status: 1 } );
} )
.then( function ( statusResult ) {
    return new Promise( function (resolve, reject) {
        console.log("updateStatus");
        resolve( { update: 2 } );
    } );
} )
.then( function ( updateResult) {
    return new Promise( function (resolve, reject) {
        console.log("getOneAppointment");
        resolve( { appointment: 3 } );
    } );
} )
.then( function( appointmentResult ) {
    return new Promise( function (resolve, reject) {
        console.log("updatedResponse");
        resolve( { update: 4 } );
    } );
} )
.then( function( updateResult ) {
    console.log("Done");
} )

【讨论】:

    【解决方案2】:

    它不起作用,因为代码没有为第二个 then 指定 return。我们需要指定return,因为我们想在之后使用then

    it("should update the status of an appointment", function(done) {
      new Promise((resolve, reject) => {
        updateStatus(testDb, 3, "In Progress", function(err) {
          if (err) reject(err);
          resolve();
        });
      })
        .then(() => {
          // specify `return` here
          return new Promise((resolve, reject) => {
            getOneAppointment(testDb, 3, function(err, appt) {
              if (err) reject(err);
              resolve(appt);
            });
          });
        })
        .then(appt => { // so we can proceed with this
          console.log(appt);
          expect(appt).deep.equal(updatedResponse);
          done();
        })
        .catch(err => {
          done(err);
        });
    });
    

    您无需在第一个承诺中指定return,因为您在此处使用done(回调)。如果你添加return,它会显示错误

    Error: Resolution method is overspecified. Specify a callback *or* return a Promise; not both.
    

    Mocha 确实可以支持 Promise(无需指定 done 作为回调)。这是没有done 的替代方案,我认为它更干净:

    it("should update the status of an appointment", function() { // remove done
      // add return
      return new Promise((resolve, reject) => {
        updateStatus(testDb, 3, "In Progress", function(err) {
          if (err) reject(err);
          resolve();
        });
      })
        .then(() => {
          // specify `return` here
          return new Promise((resolve, reject) => {
            getOneAppointment(testDb, 3, function(err, appt) {
              if (err) reject(err);
              resolve(appt);
            });
          });
        })
        .then(appt => { // so we can proceed with this
          console.log(appt);
          expect(appt).deep.equal(updatedResponse);
          // remove done()
        });
    });
    

    参考资料:

    希望对你有帮助

    【讨论】:

      猜你喜欢
      • 2018-01-06
      • 1970-01-01
      • 2016-12-30
      • 2016-02-27
      • 1970-01-01
      • 1970-01-01
      • 2018-03-18
      • 2015-01-14
      • 2015-10-16
      相关资源
      最近更新 更多