2015-03-04 2 views
0

Я работаю над проектом для моей стажировки, где они используют node.js и mongoDB в своем исходном тексте. На данный момент эта настройка работает не так хорошо, потому что на самом деле у нас есть реляционные данные, и mongoDB действительно не лучший для этого.Node.js и для шлейфов, действующих weird

Моя проблема заключается в том, что мне нужно получить некоторые данные из БД, для которых требуется «соединение» на двух таблицах. MongoDB этого не допускает, поэтому я пытаюсь сделать это вручную. Я должен найти концерт, и для каждого типа работы (JobTypeLine) у гигабайта есть информация о приглашенных сотрудниках. RolodexMembersInterested - это массив, содержащий идентификаторы, которые позволяют нам находить информацию о персонале в таблице «RolodexMember».

The JSon структур выглядеть следующим образом:

Gig:

{ 
     _id: {type: Schema.ObjectId}, 
     CreatedAt: {type: Date, default: Date.now()}, 
     EventName: {type: String, required: true}, 
     Headline: {type: String, required: true}, 
     Date: {type: Date, required: false}, 
     EndDate: {type: Date, required: false}, 
     Address: {type: String, required: false}, 
     Description: {type: String, required: true}, 
     CompanyName: {type: String, required: true}, 
     CompanyID: {type: String, required: true}, 
     Exposed: {type: Boolean, default: false}, 
     HashTags: {type: []}, 
     JobTypeLine: {type: [ 
      { 
       JobType: {type: String, required: true}, 
       Briefing: {type: String, required: false}, 
       Quantity: {type: Number, required: true}, 
       StartTime: {type: String, required: true}, 
       EndTime: {type: String, required: true}, 
       NumberOfHours: {type: String, required: false}, 
       HourlySalary: {type: Number, required: false}, 
       RolodexMembersInvited: {type: [], default: []}, 
       RolodexMembersAssigned: {type: [], default: []}, 
       RolodexMembersInterested: {type: [], default: []} 
      } 
     ]}, 
    }, 

RolodexMember:

{ 
     _id:{type:Schema.ObjectId}, 
     companyId: {type: String, required: true}, 
     userId: {type: String, required: false}, 
     userEmail: {type: String, required: true}, 
     comment: {type: String, required: false}, 
     payRate: {type: Number, required: false}, 
     name: {type: String, required: false}, 
     phone: {type: String, required: false}, 
     pictureUrl: {type: String, required: false}, 
     isHot: {type: Boolean, required: false}, 
     isInPaySystem: {type: Boolean, required: false}, 
     numberOfPreviousGigs: {type: Number, required: true, default: 0}, 
     previousGigs: [], 
     otherAttributes: [ 
      { 
       attributeName: {type: String, required: false }, 
       attributeValue: {type: String, required: false } 
      } 
     ], 
    }) 

Так что я написал метод "симулировать" мой присоединиться:

exports.getMembersInvitedToGig = function(req,res) { 

     var jobTypes = []; 
     var rolodexInvited = []; 
     gigsModel.findOne({_id: req.body.gigId}, function(err, gig) { 
      if(err) { 
       console.log(err); 
       res.send(404, "Couldn't find the gig with id: " + req.body.gigId); 
      } else { 
       for(var i=0;i<gig.JobTypeLine.length;i++){ 
        rolodexInvited = []; 
        for(var j=0;j<gig.JobTypeLine[i].RolodexMembersInvited.length;j++) { 
         var userId = gig.JobTypeLine[i].RolodexMembersInvited[j]; 
         getUserData(userId, function(data,success) { 
          if (success) { 
           rolodexInvited[j] = data; 
          } 
         }); 
        } 
        jobTypes[i] = rolodexInvited; 
       } 
       res.send(200,jobTypes); 
      } 
     }); 
    } 

    function getUserData (userId, callback) { 
     var RolodexItem = mongoose.model('RolodexItems'); 
     RolodexItem.findOne({ _id: userId }, function (err, doc) { 
      if (err) { 
       console.log("There was an error in finding the rolodex item: " + err); 
      } else { 
        callback(doc,true); 
      } 
     }); 
    } 

Моя проблема в том, что метод return и пустой массив заполняли другие пустые массивы (столько, сколько у меня естьType). Я знаю, что функция getUserData работает очень хорошо и находит нужную информацию о человеке и т. Д. Проблема заключается в том, что узел не дожидается возвращения данных внутри цикла for (j) и просто продолжается (и в конечном итоге заканчивается на res.send(200,jobTypes), в то время как jobTypes на самом деле все еще пуст. Я попытался добавить обратный вызов к getUserData для решения этой проблемы, но ничего не изменил.

(Теперь я знаю, что использование реляционной базы данных будет решать проблему все вместе , но на самом деле я не могу сказать об этом, поэтому я должен сделать эту работу такой, какой она есть). Там могут быть и очень дурные практики, поскольку я просто основывался на функциях, ранее сделанных другими людьми, и Я заметил, что они не очень хороши в этом. Я никогда раньше не работал с node.js, поэтому у меня не было времени посмотреть, как на некоторые правильные методы/и т. Д. (Не стесняйтесь указывать все, что плохо написано, я бы хотел изучить «хороший» способ сделать это)

+2

Быстрое наблюдение за 2 секундами здесь. Все операции с «базой данных» здесь на самом деле «асинхронны», но ваши базовые циклы 'for' здесь отсутствуют. Взгляните на библиотеку [async] (https://github.com/caolan/async) для возможного решения для сигнализации обратных вызовов, когда ваши фактические «операции с базой данных» завершили действия, прежде чем перейти к следующей операции. –

ответ

0

Проблема в том, что ваша функция getUserData является асинхронной (поскольку findOne является асинхронным). Поэтому цикл for не дожидается завершения вашей функции getUserData. Вы должны использовать асинхронную библиотеку (взгляните на каждую функцию): https://github.com/caolan/async

Смежные вопросы