如何用Q链接嵌套的promise?我不能让它们以正确的顺序运行

时间:2013-11-26 23:35:18

标签: javascript node.js asynchronous promise q

我希望能够将可能包含链式方法的方法链接在一起。

日志应为“第一,第二,第三”。然而,在实践中它出现了“第二,第三,第一”。

我知道这段代码有点多余,但我只是想了解promises / node是如何执行的。我如何编写可以链接在一起的基于承诺的函数?

    user.increaseReadings(id)
      .then(function(val) { console.log("second",val); return user.findById(id); })
      .then(function(val) { console.log("third",val); res.json(val); });
  }

来自/models/user模块:

exports.findById = findById;
function findById(id)  {
  deferred = Q.defer();

  User.findById(id, function(err, doc) { 
    if (err) return deferred.reject(err);
    deferred.resolve(doc);
  });

  return deferred.promise;
}

exports.increaseReadings = increaseReadings;
function increaseReadings(id) {
  deferred = Q.defer();

  findById(id).then(function(doc) {     <-- here's the problem
    doc.readings++;
    doc.save(function(err, doc) { 
      console.log("first");
      if (err) return deferred.reject(err);
      deferred.resolve(doc);
    });
  });

  return deferred.promise;
}

1 个答案:

答案 0 :(得分:2)

您可以这样重写您的increaseReadings:

function increaseReadings(id) {
    return findById(id).then(function(doc) {
        console.log(doc);
        var deferred = Q.defer();
        doc.readings++;
        doc.save(function(err, doc) { 
            console.log("first");
            if (err) return deferred.reject(err);
            deferred.resolve(doc);
        });
        return deferred.promise;
    });
}

此代码与您编写的代码之间的重要区别在于传递给'then'方法的匿名函数返回一个promise。

在大多数promise实现中,如果由于处理程序而返回promise,则在解析返回的promise之前,链中的下一步将不会执行。