【问题标题】:How to chain two promises in Node.js?如何在 Node.js 中链接两个 Promise?
【发布时间】:2014-08-13 05:34:47
【问题描述】:

我是 Node.js 的新手。我想链接两个承诺。当第一个 Promise 失败时,不应执行第二个 Promise。但是当第一个承诺失败时,我下面的代码总是执行第二个承诺。

function genQueryPromise(query, parameters) {
  var deferred = Q.defer();
  dbClient.executeAsPrepared(query, parameters,
    function(err) {
      if (err) {
        console.log(
            'error in query: ' + query + ", parameters: " + parameters);
        deferred.reject(new Error(err));
      } else {
        console.log("Query succeeded: " + query);
        deferred.resolve();
      }
    }
  );
  return deferred.promise;
}

var timeUuid = cql.types.timeuuid();
genQueryPromise(
    'INSERT INTO points_statement ' +
      '(user_id, statement_id, points_change, time_updated, note) ' +
    'VALUES (?, ?, ?, dateof(now()), ?)',
    ["mytest8",
     timeUuid,
     220,//{value: pointsChange, hint: cql.types.dataTypes.bigint},
     "test"]
  )
  .then(genQueryPromise(
    'UPDATE user_points SET points = points + ? WHERE user_id = ?',
    [{value: 220, hint: cql.types.dataTypes.bigint}, "mytest8"]
  ))
  .fail(function (error) {
    console.log("db error " + error);
  });

输出如下:

error in query: INSERT INTO points_statement (user_id, statement_id, points_change, time_updated, note) VALUES (?, ?, ?, dateof(now()), ?), parameters: mytest8,b5835850-2266-11e4-a871-f1a82b5a7753,220,test
db error Error: ResponseError: Expected 8 or 0 byte long (4)
Query succeeded: UPDATE user_points SET points = points + ? WHERE user_id = ?

你可以看到,即使第一个 promise 失败,第二个 promise 也被执行了。我做错了什么?谢谢。

【问题讨论】:

    标签: javascript node.js promise q


    【解决方案1】:

    您在构建承诺链时调用了genQueryPromise。在链中调用它:

    genQueryPromise(
        'INSERT INTO points_statement ' +
          '(user_id, statement_id, points_change, time_updated, note) ' +
        'VALUES (?, ?, ?, dateof(now()), ?)',
        ["mytest8",
         timeUuid,
         220,//{value: pointsChange, hint: cql.types.dataTypes.bigint},
         "test"]
      )
      .then(function() {
        return genQueryPromise(
          'UPDATE user_points SET points = points + ? WHERE user_id = ?',
          [{value: 220, hint: cql.types.dataTypes.bigint}, "mytest8"]
        );
      })
      .fail(function (error) {
        console.log("db error " + error);
      });
    

    添加一个函数包装器,以便在第一次调用完成后执行第二次调用,而不是同时执行。

    【讨论】:

    • 它有效!所以 then() 中的参数应该是返回 promise 的函数,而不是 promise 本身。对吗?
    • @Kai 应该传入一个函数到then,这个函数会在链中前一个promise被解析后执行。如果函数返回一个promise,它将被插入到链中。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-26
    • 2020-03-14
    • 1970-01-01
    • 2018-05-16
    • 2020-10-10
    • 1970-01-01
    相关资源
    最近更新 更多