如何控制node.js中的执行流程

时间:2015-12-03 08:52:23

标签: node.js mongodb mongoose

以下是我的功能。它不是计算分数,而是最初将分数作为0发送给调用者,然后进入查询并计算分数但不返回分数。它然后回到调用者。请帮帮我。

function calculateScore(questionMaster,examid) {
    var score=0,arr=[];
    console.log(questionMaster);
    console.log(questionMaster[0].answers);
    console.log(questionMaster[0].answers.questionId); 
    for(var i=0;i<questionMaster[0].answers.length;i++) {
      arr[i] = mongoose.Types.ObjectId(questionMaster[0].answers[i].questionId);
    }
    console.log(arr); 
    examMasterModel.aggregate([{$match: {examid:examid}}, 
                               {$unwind: "$questionMaster"}, 
                               {$project: {questionMaster: 1 }},
                               {$match: {"questionMaster._id": {$in: arr}}}], 
                               function(err,questions){
      console.log(questions);
      for(var i=0; i<questions.length; i++) {
        if(questionMaster[0].answers[i].answer == decrypt(questions[i].questionMaster.answer)) {         {
          score++;
          console.log(questionMaster[0].answers[i].answer);
          console.log( decrypt(questions[i].questionMaster.answer));
          console.log(score);
        }
        else{
          console.log('in else');
        }
        console.log('in loop');

      }

    }); 
    return score; 
} 

2 个答案:

答案 0 :(得分:0)

examMasterModel.aggregate是一个异步函数,您可以为其发送回调函数。异步功能&#39;回调是在未知时间执行的,超出了代码的正常流程。

您的代码中发生了什么,是您调用异步函数,然后返回score,然后才执行回调(并且更改score太晚了。)

解决方案是使calculateScore函数异步(将回调函数作为参数或使用promises),并在score之后返回值calculateScore计算

<强> 实施例

使用回调:

function calculateScore(questionMaster, examid, callback) { var score = 0; examMasterModel.aggregate([...], function(err, questions) { //your logic to calculate score callback(score); }); } 功能修改为:

calculateScore

确保在致电calculateScore(param1, param2, function(calculatedScore) { score = calculatedScore; }); 时,您传递了回调函数。例如:

npm install q

承诺:

假设您未使用ES6,则应require('q'),然后在代码function calculateScore(questionMaster, examid) { var score = 0; var deferred = q.defer(); examMasterModel.aggregate([...], function(err, questions) { //your logic to calculate score deferred.resolve(score); }); //note that this is in the main flow of the function, outside of the async call return deferred.promise; } 中。之后,语法如下:

calculateScore

然后你可以像calculateScore(param1, param2).then(function(calculatedScore) { score = calculatedScore; }); 那样打电话:

AttributeConverter

一些有用的阅读材料:

https://github.com/kriskowal/q

答案 1 :(得分:0)

您可以使用Promise来控制流程

var Promise = require("bluebird");
Promise.promisifyAll(require("mongoose"));

之后,每个函数都会有一个像aggregateAsync这样的异步版本,您可以像这样调用

return mongoose.aggregateAsync() //....
    .then(function (resultFromAbove) {
        var score
        // do your things with score
        return score
    })