【问题标题】:NodeJs Mongoose collecting data in loopNodeJs Mongoose 循环收集数据
【发布时间】:2015-12-26 03:40:43
【问题描述】:

希望得到您的帮助。

我有收集任务,其中包含类似此架构的文档。

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

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

代码在这里:

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

【问题讨论】:

    标签: javascript arrays node.js mongodb mongoose


    【解决方案1】:

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

    【讨论】:

    • 作者正在寻找时间问题的答案,而不是重复他已经知道的内容。
    【解决方案2】:

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

    var countdown = doc.performers.length;
    

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

    但您的代码仍然看起来不是很高效。有很多对数据库的调用。也许您可以重新考虑您的数据模型,以尽量减少对数据库的调用。

    【讨论】:

    • 对柜台感兴趣的想法,会尝试..我怎样才能最大限度地减少通话?
    • 只是为了完整性:对于带有少量数据库调用的解决方案:请参阅@Khay 的答案
    【解决方案3】:

    问题是您需要在 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
        });
      });
    })
    

    【讨论】:

    猜你喜欢
    • 2013-12-22
    • 2020-04-17
    • 1970-01-01
    • 2015-10-24
    • 2018-04-07
    • 2020-12-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多