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

Issue while getting array value in NodeJS

本文关键字:问题 数组 NodeJS 获取      更新时间:2023-09-26

我使用NodeJS来计算不同部分的员工数量。我使用猫鼬作为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[i]的值在Issue.count({ 'section.name': array[i]}, function (err, count) {});中没有定义。但是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

这是因为Issue.count({ 'section.name': array[i]}, function (err, count) {});里面的i的值总是2。

是否可能是问题。计数函数是异步的?所以你的循环在

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

执行。当执行回调函数时,i的值作为结果是未定义的。

@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]));
}

不要尝试使用常规的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')
  }
)

使用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()