2013-10-09 5 views
0

Я пытаюсь получить информацию для 2-х элементов и информацию о пользователе для каждого элемента (a, b, c) с помощью следующего кода. Однако у меня проблема, когда он показывает повторяющиеся результаты и неожиданный вывод.Nodejs loop with callback

  • FindItem
  • findUser A A
  • findUser а
  • FindItem гр
  • findUser гр
  • Результаты
  • FindItem б
  • findUser б
  • Результаты
  • findUser б
  • результаты

(Существует только один пункт для пункта «с»)

Я ожидал увидеть результаты только один раз.

var results = []; 
var items = ['a', 'b', 'c']; 

function async(item, callback) {   
    findSomething(2, item, function(err, items){ 
    if (err) throw err; 
    console.log('findItem ' + item); 
    var item = []; 
    _.map(items, function(value, key) { 
     findSomethingElse(items[key].id, function(err, name){ 
     if(err) throw err; 
     console.log('findUser ' + item); 
     item['name'] = name;    
     item['items'] = items[key];    
     callback(item); 
     }); 
    });  
    }); 
} 

function final() { 
    console.log('results'); 
    // return results; 
} 

function series(item) { 
    if(item) { 
    async(item, function(result) { 
     results.push(result); 
     return series(items.shift()); 
    }); 
    } else { 
    return final(); 
    } 
} 
series(items.shift()); 

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

var results = []; 
var items = ['a', 'b', 'c']; 

async.each(items, findItem, function(err){ 
    if(err) throw err; 
}); 

function findItem(item) { 
    Bid.findBids(2, item, function(err, bids){ 
    if (err) throw err; 
    async.each(bids, findUser, function(err){ 
     if(err) throw err; 
    }); 
    }); 
} 

function findUser(item) { 
    User.findBidder(item.email, function(err, user){ 
    if(err) throw err; 
    var bid = []; 
    bid['user'] = user;    
    bid['item'] = item;   
    results.push(bid); 
    }); 
}  

function done() { 
    console.log('Results: ' + results); 
    return results; 
} 
+0

Вы видели https://github.com/caolan/async? – Wex

+0

Спасибо, я обновил свой вопрос, используя предлагаемый модуль – drewsdesign

ответ

0

Вот одно из возможных решений с использованием асинхронных очередей:

var results = []; 
var items = ['a', 'b', 'c']; 

// We assume items[] isn't empty, and create a queue 
// to process each item. 
var itemQueue = async.queue(function (item, nextItem) { 
    // For each item get the bids 
    Bid.findBids(2, item, function(err, bids){ 
    if (err) throw err; 

    // If no bids go to next item 
    if (bids.length === 0) { 
     nextItem(); 
    } else { 
     // Otherwise loop through bids with another queue 
     var bidQueue = async.queue(function (bid, nextBid) { 
     User.findBidder(item.email, function(err, user){ 
      if(err) throw err; 
      var bid = []; 
      bid['user'] = user;    
      bid['item'] = item;  
      results.push(bid); 
      nextBid(); 
     }); 
     }); 

     // When all bids are done, go to next item. 
     bidQueue.drain = function() { 
     nextItem(); 
     }; 

     // place all bids on the queue for this item. 
     bidQueue.push(bids); 
    } 
    }); 
}); 

// When all items are done, print the results 
itemQueue.drain = function() { 
    console.log('Results: '); 
    console.log(results); 
} 

// push all the items onto the queue - note that if items is 
// empty, drain() will never be called! 
itemQueue.push(items); 
+0

Большое вам спасибо, это именно то, что я искал – drewsdesign