2

请看下面的代码片段。我希望只有在获得第一个查询的结果后才执行第二个 MongoDB 查询。但正如您可以想象的那样,它不会按照那个顺序发生。

db.collection('student_profile', function (err, stuColl) {
  //This if-else can be refactored in to a seperate function
  if (req.params.stuId == req.header('x-stuId')) {
    var stuInQuestion = student;
  } else {
    var stuInQuestionId = new ObjectID.createFromHexString(req.params.stuId);
    stuColl.findOne({
      '_id': stuInQuestionId
    }, function (err, stuInQuestionObj) {
      if (!stuInQuestionObj) {
        process.nextTick(function () {
          callback(null);
        });
      } else {
        var stuInQuestion = stuInQuestionObj;
      }
    });
  }

  stuColl.find({
    '_id': {
      $in: stuInQuestion['courses']
    }
  }).limit(25).sort({
    '_id': -1
  }).toArray(function (error, courses) {
    if (error) {
      process.nextTick(function () {
        callback(null);
      });
    } else {
      process.nextTick(function () {
        callback(courses);
      });
    }
  });
});

那么我在这里的选择是什么?

  1. 有没有办法以不需要任何控制流库的方式对此进行编码?如果是的话,有人可以告诉我怎么做吗?

  2. 如果这确实需要使用控制流库,我应该使用哪一个?异步,FuturesJs,还有什么?

4

2 回答 2

4

您不需要任何控制流库,因为这些库只是在后台使用回调。

尝试这样的事情:

db.collection('student_profile', function (err, collection) {

  // Suppose that `firstQuery` and `secondQuery` are functions that make your
  // queries and that they're already defined.
  firstQuery(function firstCallback(err, firstRes) {

    // Do some logic here.

    // Make your second query inside the callback
    secondQuery(function secondCallback(err, secondRes) {
      // More logic here
    });
  });
});

基本上,您要做的是从第一个查询的回调中调用您的第二个查询。

这可能会让你觉得嵌套很深。如果这成为一个问题,您可以通过定义函数而不是内联所有函数以及将逻辑包装在模块中来缓解它。

于 2012-05-22T04:30:33.497 回答
0

我会创建一个findStudent函数并让两种情况都调用它:

db.collection('student_profile', function (err, stuColl) {
  //This if-else can be refactored in to a seperate function
  if (req.params.stuId == req.header('x-stuId')) {
    return findStudent(student);
  } else {
    var stuInQuestionId = new ObjectID.createFromHexString(req.params.stuId);
    stuColl.findOne({
      '_id': stuInQuestionId
    }, function (err, stuInQuestionObj) {
      if (!stuInQuestionObj) {
        process.nextTick(function () {
          callback(null);
        });
      } else {
        return findStudent(stuInQuestionObj);
      }
    });
  }

  function findStudent(stuInQuestion) {
    stuColl.find({
      '_id': {
        $in: stuInQuestion['courses']
      }
    }).limit(25).sort({
      '_id': -1
    }).toArray(function (error, courses) {
      if (error) {
        process.nextTick(function () {
          callback(null);
        });
      } else {
        process.nextTick(function () {
          callback(courses);
        });
      }
    });
  }
});
于 2012-05-22T04:26:50.243 回答