NodeJs:amync forEach在mongoose中查找

时间:2016-08-17 08:48:30

标签: node.js mongodb foreach

我想那些熟悉Node.js和Mongoose的人应该很简单。 我正在尝试将最终结果放在异步forEach和mongoose中,我可以在函数中间看到结果很好,但是当我试图在第二个forEach之后得到它时,我不能。

我试图抓住最后一次迭代并返回结果,但因为它是异步的,所以最后一次迭代在函数中间的find之前到达。

有什么建议吗?这就是我所拥有的:

function addUsersInfoForEachVote(req, res, next){
    var itemsProcessed = 0;
    Questions.findOne({_id: req.body.question}, {answers: 1}).exec(function (err, question) {
        var finalVotes = [];
        if (err | !question) {
            return res.send({
                errors: err | "No Question Found"
            });
        } else {
            question.answers.forEach((answer, index, array) => {
                var votedUsers = [];
                votedUsers = votedUsers.concat(answer.get("votes"));
                answer._doc.votes = answer.get("votes").length;
                var ansId = answer.answerId;
                var aData = {answer: answer, users: {}};
                AnswersVote.find({'_id': {$in: getUniqueIds(votedUsers)}},{user: 1})
                           .populate('user', 'name gender')
                           .exec(function(err, votesUsers){
                                if (!err) {
                                    votesUsers.forEach(function(vote){
                                        var user = vote.get("user");
                                        if (user){
                                            aData.users[user.get("id")] = user;
                                        }
                                    });
                                    console.log("ADATA:"+JSON.stringify(aData)); //Here I can see it well! (the second time contain it all)
                                }
                            });
                //currAns = votedUsers;
                itemsProcessed++;
                if( itemsProcessed === array.length) {
                //HERE I NEED THE FINAL RESULTS:
                    console.log("ADATA after:"+JSON.stringify(aData));
                    next();
                }
            });    
        }

    });
}

3 个答案:

答案 0 :(得分:1)

您可以使用async eachLimit或每个Read doc(http://caolan.github.io/async/docs.html#.eachLimit)

String url = driver.getCurrentUrl();
// If you want to navigate to first 2nd page you can append the `start` with some value in the multiple of 10th.
// so for 7th page it would be `start=60`
// for nth page it would be `start = n*10 - 10`
String newURL = url + "&start=" + n*10 - 10
driver.Navigate().GoToUrl(newURL);

答案 1 :(得分:0)

您可以使用async.waterfall来达到预期效果。

有关详细信息,请参阅doc

尝试以下代码: -

function addUsersInfoForEachVote(req, res, next){
var itemsProcessed = 0;
  Questions.findOne({_id: req.body.question}, {answers: 1}).exec(function (err, question) {
    var finalVotes = [];
      if (err | !question) {
          return res.send({
              errors: err | "No Question Found"
          });
     } else {
question.answers.forEach((answer, index, array) => {
  var votedUsers = [];
    votedUsers = votedUsers.concat(answer.get("votes"));
    answer._doc.votes = answer.get("votes").length;
var ansId = answer.answerId;
var aData = {answer: answer, users: {}};

async.waterfall([
     function(callback){
       AnswersVote.find({'_id': {$in: getUniqueIds(votedUsers)}},{user: 1}).populate('user', 'name gender').exec(function(err, votesUsers){
        if (!err) {
            votesUsers.forEach(function(vote){
                var user = vote.get("user");
                if(user){
                aData.users[user.get("id")] = user;
              }
            });
          console.log("ADATA:"+JSON.stringify(aData)); //Here I can see it well! (the second time contain it all)

          callback(null);
        }
      });
    },
    function(callback){
         //currAns = votedUsers;
    itemsProcessed++;
    if(itemsProcessed === array.length) {
       //HERE I NEED THE FINAL RESULTS:
         console.log("ADATA after:"+JSON.stringify(aData));
          callback(null);
        }
     else {callback(null);}
    }
], function(err){next();})
});

这可能会对你有所帮助。如果有效,请告诉我。

答案 2 :(得分:0)

首先,谢谢大家的帮助,我个人试图避免使用外部库,如果没有必要,并且因为我之前可以查看答案数量,这里是正确答案:

function addUsersInfoForEachVote(req, res, next){
      Questions.findOne({_id: req.body.question}, {answers: 1}).exec(function (err, question) {
        var finalVotes = [];
          if (err || !question) {
              return res.send({
                  errors: err || "No Question Found"
              });
          } else {
        var ansNum=0; //FOR MY ITERATIONS
        var fAns = {full : {}}; //FOR MY FINAL ANSWER

        //Here, I can assume we have only two answers so:
    question.answers.forEach(function (answer) {
      var votedUsers = [];
        votedUsers = votedUsers.concat(answer.get("votes"));
        answer._doc.votes = answer.get("votes").length;
        //answer._doc.answer = votedUsers;
      var ansId = answer.answerId;
      var aData = {answer: answer, users: {}};

  AnswersVote.find({'_id': {$in: getUniqueIds(votedUsers)}},{user: 1}).populate('user', 'name gender').exec(function(err, votesUsers){
            if (!err) {
                votesUsers.forEach(function(vote){
                    var user = vote.get("user");
                    if(user){
                    aData.users[user.get("id")] = user;
                  }
                });
            }
fAns.full[ansId] = aData;
if(ansNum > 0){ //The number of the answers here is "2", but this value can be changed
  console.log("FINAL:"+JSON.stringify(fAns)); //Here I have the full response now :)
  res.jsonp(fAns);
}
            ansNum++;
        });
    });

          }

        });

      }

无论如何,再次感谢。