2016-05-21 4 views
1

У меня есть метод, который возвращает список шоу с последними релизами эпизодов, которые возвращают общее количество эпизодов. Я как бы застрял в цикле, где мне нужно подсчитать все эпизоды шоу в приведенном массиве, поскольку запрос вызова асинхронный, и я не могу их синхронизировать. Это здорово, что может предложить решение этой проблемыLoopback Async data call Nodejs

server.models.Eps.find({ 
    include:'show', 
    order: 'dateadded DESC', 
    limit: 10 },function (err,episodes) { 
    if(err) 
    { console.log(err); 
    return res.sendStatus(500); 
    } 
    var show = []; 
    var p1 = new Promise(function (resolve,reject) { 
    for(var i = 0; i < episodes.length;i++) 
    { 
     var sh = episodes[i].show(); 
     server.models.Eps.count({'show_id': show.id},function (err,value) { 
     if(err) { 
      console.log(err); 
      return res.statusCode(500); 
     } 
     console.log(value); 
     sh.episodeCounts = value; 
     show.push(sh); 
     }); 
    } 
    }); 
    Promise.all([p1]) 
    .then(function (values) { 
     return res.send(show); 
    }); 
}); 

ответ

0

Несколько вещей, чтобы указать здесь. show определяется как пустой массив, но тогда идентификатор ссылается на запрос server.models.Eps.count({'show_id': show.id},function (err,value) {. Я предполагаю, что шоу является ключом к структуре данных эпизода, поэтому не должен быть вызовом функции? Также я не уверен, почему вы используете Promise.all за одно обещание.

Я думаю, что понимаю, чего вы пытаетесь достичь.

Есть несколько способов, которыми вы могли бы это сделать, для тех, которые требуют наименьших изменений и которые, вероятно, будут считаться более приятными.

  1. Вы можете использовать библиотеку async перебрать массив асинхронно. Он должен работать нормально, но это не очень хорошо смешивать обратные вызовы и обещания таким образом (мое личное мнение :))

    var async = require("async"); 
    var shows = []; 
    
    async.each(episodes, function(episode, cb){ 
        var show = episode.show; 
        server.models.Eps.count({'show_id': show.id},function(err,value) { 
        if(err) { 
         console.log(err); 
         cb(err); 
        } 
        console.log(value); 
        show.episodeCounts = value; 
        shows.push(sh); 
        }, 
        function(err){ 
        if(err){ 
         return res.statusCode(500); 
        } 
        else callback(); 
        }); 
    }); 
    
  2. Другая вещь, которую вы могли бы сделать, это обернуть функцию server.models.Eps.count в обертку, которая возвращает Обещание. Таким образом, вы можете использовать более перспективный метод работы с асинхронными вызовами. Что-то вроде:

    server.models.Eps.find({ 
        include:'show', 
        order: 'dateadded DESC', 
        limit: 10 },function (err,episodes) { 
        if(err){ 
        console.log(err); 
        return res.sendStatus(500); 
        } 
        var promises = []; 
        for(var i = 0; i < episodes.length;i++) 
        var show = episodes[i].show; 
        promises.push(appendEpisodeCount(show)); 
        } 
        Promise.all(promises) 
        .then(function(shows) { 
         return res.send(shows); 
        }) 
        .catch(function(err){ 
         res.statusCode(500); 
        }); 
    }); 
    
    function appendEpisodeCount(show) 
        var promise = new Promise(function(resolve, reject){ 
        var query = { 
         show_id: show.id 
        }; 
        server.models.Eps.count(query,function(err,value) { 
         if(err) return reject(err); 
         show.episodeCount = value; 
         resolve(show); 
        }); 
        }); 
        return promise; 
    } 
    
+0

Оооо !! это была ошибка, когда я создавал этот код для потока Stackover, исправил «server.models.Eps.count ({'show_id': sh.id}, function (err, value) {". Что касается "Promises.all «Есть больше обещаний в вышеприведенном коде, просто чтобы сделать код короче и достаточно быстро, чтобы понять, что я их удалил. Должен был добавить пустое обещание для завершения ситуации. – tecx20

+0

Спасибо, что сделал трюк, решил пойти со вторым подходом – tecx20