2

我正在使用 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[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

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

4

4 回答 4

3

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

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

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

于 2013-04-19T12:37:44.213 回答
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]));
}
于 2013-04-19T12:55:51.563 回答
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')
  }
)
于 2013-04-19T14:49:40.283 回答
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()
于 2017-07-28T08:51:41.497 回答