2012-05-22 36 views
2

请看下面的代码片段。我希望第二个mongodb查询只有在得到第一个结果后才能执行。但正如你所能想象的那样,它并不是按照这个顺序发生的。如何强制一个调用在node.js中同步

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,还有什么?

感谢, --su

回答

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); 
     }); 
     } 
    }); 
    } 
}); 
+0

@丹....我采取了你的建议,因为它看起来像简单的一个。有用。谢谢大家的意见。 –

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 
    }); 
    }); 
}); 

基本上,你想要做的是从你第一次查询的回调里面打电话给你的第二个查询。

这可能会导致你深陷其中。如果这成为一个问题,你可以通过定义你的函数而不是内联所有这些函数来减轻它,并且通过在模块中包装逻辑。

+0

@Joshua ...感谢您的回复。我熟悉嵌套构造,并在代码中的多个位置使用它。但上述情况不同。我有一个if-else构造。第一个查询在else部分。第二个查询在if-else之外,并且需要在if-else从句中满足哪个条件时执行。因此,无需重复代码(if和else部分中的代码相同)就很难嵌套这个代码。您的帮助非常值得赞赏。 –

相关问题