NodeJs Mongoose循环收集数据

NodeJs Mongoose collecting data in loop

本文关键字:数据 循环 Mongoose NodeJs      更新时间:2023-09-26

希望得到您的帮助。

我有这样的文档模式的收集任务。

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

最后,我应该收集所有数据,并返回配置文件对象的数组。问题是for循环在完成所有元素的. findone()之前结束,并且它返回空数组。这是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});
});    

问题是您需要在猫鼬查询中返回响应。您不能在外部使用查询内部分配的任何值。例如:

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

一个简单的想法是在开始for循环之前引入一个倒计时计数器,如下所示:

var countdown = doc.performers.length;

递减findOne-Calls回调函数的倒数。检查是否已达到0,并调用外部函数发送结果。

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

for循环将在findOne完成之前完成