2015-09-20 4 views
0

Я работаю над простой службой чата с использованием mongoose и nodejs.Объединение нескольких коллекций на уровне приложений с помощью Mongoose

У меня есть две модели для обмена сообщениями для чтения информации;

var ChatModel = new Schema({ 
    to: String, 
    from: String, 
    message: String, 
    time: {type: Date, default: Date.now} 
}); 

var InfoModel = new Schema({ 
    reader: String, 
    from: String, 
    time: {type: Date, default: Date.now} 
}); 

Когда кто-то (читатель) проверяет его/ее входящие сообщения от кого-то другого (с) я просто поставил рекорд по InfoModel.

Я хочу найти отдельных отправителей, которые отправили сообщения (скажем) T1 с информацией о чтении.

  Chat.distinct('from', {to: 'T1'}) 
      .then(
      function (data) {     
       res.json(data); 
      }) 

имея найти различные отправители мне как-то нужно перебрать отправитель и получать последние времена сообщений для каждого из них. Вот то, что я пытался сделать, но не получилось

  Chat.distinct('from', {to: 'T1'}) 
      .then(
      function (data) { 
       for (var i = 0; i < data.length; i++) { 
        Chat.findOne({from: data[i], to:'T1'}, 'time', {sort: {'time': -1}}) 
         .then(function(d){ 
          ... I need to fetch from InfoModel and compare the dates for read/unread information 
         } 

        ) 
       } 
       res.json(result); 
      }) 

но, очевидно, этот подход не работает, как нужно все записи пришли из findOne готовы и получить информацию от InfoModel.

Ну, просто мне нужно что-то синхронизировать, или я должен думать асинхронно, не знаю, как это сделать.

ответ

0

Асинхронные функции в цикле for не являются хорошей практикой.

Цикл for не ждет, когда функции async вызовут его обратный вызов (который заканчивает работу). Он будет перебирать целую петлю так быстро, потому что ей не нужно ждать асинхронных функций, а затем запускает res.json(result);, даже если первые Chat.findOne({from: data[0] .... еще не закончили работу и вызывают обратный вызов.

for (var i = 0; i < data.length; i++) { 
    Chat.findOne({from: data[i], to:'T1'}, 'time', {sort: {'time': -1}}) 
    .then(function(d){ 
     // ... I need to fetch from InfoModel and compare the dates for read/unread information 
    }) 
} 

/** 
This res.json would be fired even the first Chat.findOne not yet finished. 
*/ 
res.json(result); 

Вы должны сделать итерацию ждать до тех пор пока все данные извлекаются из моделей, а затем вы можете сделать res.json(result); их обратный вызов.

Вы всегда можете управлять потоком данных async с этим удивительным async node.js npm module.

Надеюсь, вы пригвоздили эту проблему! :)