2013-04-19 3 views
2

Я использую NodeJS для подсчета количества сотрудников в разных разделах. Я использую Mongoose как ODM и MongoDB как базу данных. Это мой код (очень простой для тестирования).Проблема при получении значения массива в NodeJS

exports.list= function(req, res){ 
    var array = ['sectionA', 'sectionB']; 
    var i; 
    for(i = 0; i<array.length; i++){ 
     Issue.count({ 'section.name': array[i]}, function (err, count) { 
      console.log('Section name is: ' + array[i] + ' number of employees: ' + count); 
     )}; 
    } 
    } 

Но значение array[i] не определено внутри Issue.count({ 'section.name': array[i]}, function (err, count) {});. Но ценность счета абсолютно правильная. Я хочу, чтобы выход, как:

Section name is: sectionA number of employees: 50 
Section name is: sectionB number of employees: 100 

Но мой выходной ток

Section name is: undefined number of employees: 50 
Section name is: undefined number of employees: 100 

Это потому, что значение i внутри Issue.count({ 'section.name': array[i]}, function (err, count) {}); всегда 2.

ответ

2

@eshortie верен: Issue.count является асинхронным, и это вызывает проблему.

Вот решение:

for (i = 0; i<array.length; i++) { 
    Issue.count({ 'section.name': array[i]}, function(sectionName, err, count) { 
    console.log('Section name is: ' + sectionName + ' number of employees: ' + count); 
    }.bind(null, array[i])); 
} 
3

Возможно ли, что функция Issue.count является асинхронный? Таким образом, ваша петля завершается до обратного вызова:

function (err, count) { 
    console.log('Section name is: ' + array[i] + ' number of employees: ' + count); 
} 

Выполнено. Когда обратные вызовы выполняются, значение i в результате не определено.

2

Не пытайтесь выполнять асинхронные функции с помощью обычного for цикла. Он задает проблемы. Используйте async.eachSeries или async.each вместо https://github.com/caolan/async#eachseriesarr-iterator-callback

var async = require('async') 
var Issue = {} // mongoose isue model here 
var elements = ['foo', 'bar'] 
async.eachSeries(
    elements, 
    function(name, cb) { 
    var query = { 
     'section.name': name 
    } 
    Issue.count(query, function(err, count) { 
     if (err) { return cb(err) } 
     console.dir(name, count) 
    }) 
    }, 
    function(err) { 
    if (err) { 
     console.dir(err) 
    } 
    console.log('done getting all counts') 
    } 
) 
0

Использование Q библиотеки

var Q = require('q') 
    var i = 0; 

    function hello (item){ 

     var defer = Q.defer(); 

     Issue.count({'section.name': student}, function (err, count) { 
       if(err){ 

       defer.reject(err); 

       }else{ 

       var result = 'Section name is: ' + item + ' number of employees: ' + count ; 
       defer.resolve(result) 

       } 

      }); 

    }) 
      return defer.promise; 
     } 


     function recall(){ 
     hello(checkItems[i]).then((val)=>{ 
      console.log(val) 
      if(i < checkItems.length - 1){ 
      i++ 
      recall(); 
      } 
     }) 
     } 
    recall()