2016-11-25 3 views
0

У меня проблема с обработкой огромного набора данных в NodeJS. Я использую async, потому что я хочу позвонить res.send, когда все будет готово.NodeJS async большой обратный вызов набора данных

Казус:

В коллекции MongoDB по этому проекту можно добавить кампании. Магазины могут присоединиться к этим кампаниям и добавить некоторые действия из этой кампании в повестку дня. (например, сообщение в Facebook, фотография в Instagram) На интерфейсе сайта есть страница, на которой показаны все активные кампании. Когда кампания открыта, должен быть список со всеми магазинами, которые присоединились к этой кампании.

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

Проблема:

Как вы можете видеть в приведенном ниже коде, я получаю все магазины, и цикл по элементам. Затем я просматриваю элементы повестки дня, чтобы увидеть, существует ли соответствующий идентификатор кампании, а затем добавляю некоторую информацию в массив, которую я хочу отправить обратно. Но код останавливается после 1 магазина. Как добавить все магазины в массив и отправить все, когда все магазины будут обработаны?

Shopmodel:

(не все поля)

var Shop = new Schema({ 
    name:String, 
    email:String, 
    phone: String, 
    agenda:[{ 
     campaignId:Schema.ObjectId, 
     taskId:Schema.ObjectId, 
     campaignName: String, 
     downloaded: Boolean, 
     success: Boolean, 
     startDate:Date, 
     endDate:Date, 
     description:String, 
     kind:String 
    }], 
},{collection:'shop'}); 

код в контроллере:

module.exports.getCampaignShop = function(req,res){ 
    console.log("getCampaignShop"); 
    var campaignId = req.query['campaignId']; 
    console.log("campaignId", campaignId); 
    var result = []; 
    Shop.find().sort({name:1}).exec(function(err, shops){ 
     console.log("shop count", shops.length); 
     async.eachSeries(shops, function(shop, allDone){ 
      async.eachSeries(shop.agenda, function(agenda, shopComplete){ 
       if(agenda.campaignId == campaignId){ 
        var shopResult = { 
         shopId: shop._id, 
         nameSlug: shop.nameSlug, 
         logo: shop.logo, 
         name: shop.name 
        } 
        console.log("shopResult", shopResult); 
        result.push(shopResult); 
        shopComplete(); 
       } 
      }) 
      allDone(); 
     }, function(err){ 
      if (err) throw err; 
      console.log("result length", result.length); 
      res.send(result); 
     }) 

    }) 
} 
+0

Вы пытались составить запрос, который возвращает только магазин, где> 1 элемент в повестке дня имеет campaingnId, равный тому, что вы хотите? MongoDB может облегчить ваше время – DrakaSAN

ответ

2

Выпуск shopComplete обратного вызова вызываются только тогда, когда agenda.campaignId == campaignId является True. Вы должны позвонить ему за пределами if block.

+0

Да! Это был трюк! – NVO

+0

Также предложите NVO запустить синхронизацию вместо 'async.eachSeries (shop.agenda, function (Agenda, shopComplete) {', поскольку я не могу понять, зачем вам нужен async. –

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

  • Нет связанных вопросов^_^