在NodeJS中获取数组值时出现问题

时间:2013-04-19 12:09:17

标签: javascript node.js express mongoose

我使用NodeJS来计算不同部分的员工数量。我使用Mongoose作为ODM,使用MongoDB作为数据库。这是我的代码(非常简单,用于测试目的)。

   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[iIssue.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

这是因为iIssue.count({ 'section.name': array[i]}, function (err, count) {});的值始终为2。

4 个答案:

答案 0 :(得分:3)

Issue.count函数是否可能是异步的?所以你的循环在回调之前完成:

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

已执行。执行回调时,结果是i的值未定义。

答案 1 :(得分: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]));
}

答案 2 :(得分:2)

不要尝试使用常规for循环执行异步函数。这是在寻找问题。使用async.eachSeriesasync.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')
  }
)

答案 3 :(得分: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()