NodeJs Mongoose在循环中收集数据

时间:2015-09-28 19:56:11

标签: javascript arrays node.js mongodb mongoose

希望得到你的帮助。

我的收集任务包含此架构之类的文档。

Task = { 
     title:'taskName', 
     performers:[ {userId:1,price:230}, {userId:2,price:260} ]
}   
Profiles = { id:1, name: 'Alex', surname: 'Robinson', etc.. }

最后,我要收集所有数据,并在响应中返回配置文件对象的数组。问题是在为每个元素完成所有.findOne()之前的for循环结束,并且它返回空数组。 这是代码形式get。

此处的代码:

apiRoutes.get('/performers/:id', function(req,res,next){

var profArr = []; 
Task.findOne({'_id':req.params.id},function(err, doc){
  for(var i = 0; i<doc.performers.length; i++){
    var profile = {
      price: 0,
      name: '',
      surname: ''         
    };
    profile.price = doc.performers[i].price;
    Profile.findOne({'_id':doc.performers[i].userId},function(err,doc){
      if (err) throw err;
      profile.name = doc.name;
      profile.surname = doc.surname;          
      profArr.push(profile);
    });
  }
  return res.json({success:true,
                   message:'Performers data collected',
                   data:profArr});
});    

3 个答案:

答案 0 :(得分:0)

一个简单的想法是在开始你的for循环之前引入一个倒数计数器:

var countdown = doc.performers.length;

减少findOne-Calls回调函数的倒计时。检查是否已达到0并在外面调用函数以发送结果。

但是你的代码看起来效率仍然不高。 db有很多调用。也许你可以重新考虑你的数据模型,以便最小化对db的调用。

答案 1 :(得分:0)

问题是您需要在mongoose查询中返回响应。您不能使用外部查询中指定的任何值。例如:

var sampleArr = [];
Users.find({}, function(err, users) {
  users.forEach(function(user) {
    Students.find({'userid' : user.id}, function(err, student) {
      sampleArr.push({
        'student' : student
      });
    })
    console.log(sampleArr);
    // It will only return empty array[];
  })
})

所以,你的任务应该是这样的:

apiRoutes.get('/performers/:id', function(req,res,next){

var profArr = [];
// Get a task by ID
Task.findById(req.params.id, function (err, task) {
  // Get all profiles
  Profile.find({}, function (err, profiles) {
    task.performers.forEach(function(taskPerformer) {
      profiles.forEach(function(profile) {
        // Check the performer ID is the same with userID or not
        if (profile._id == taskPerformer.userId) {
          profArr.push({
            price: taskPerformer.price,
            name: profile.name,
            surname: profile.surname
          });
        }
      })
    });
    return res.json({
      success:true,
      message:'Performers data collected',
      data:profArr
    });
  });
})

答案 2 :(得分:-2)

你的“for”循环将在findOne完成之前完成。