运行 查询nodejs中的集合项

Running query on collection items in nodejs

所以我很困惑,似乎无法理解发生了什么。我有一个接受订单数组的函数。

var collection = [{ordernumber: 1, href: 'FileDetails.aspx?FileId=1234'}, 
                  {ordernumber: 2, href: 'FileDetails.aspx?FileId=1478'}];
var OrdersListToImport = [];

function loopOrders(collection, callback) {
  for(var i = 0; i < collection.length; i++) {
    console.log('processing order #: ' + collection[i].ordernumber);
    var answersReturned = 0;
    db.needsImported(collection[i].ordernumber, function(answer) {
      if (answer) {
        OrdersListToImport.push(collection[i]);
        //console.log(collection[i]);
      }
      if (++answersReturned == collection.length) {
        callback();
      }

    });
  }

}

需要导入功能如下:

needsImported: function(ordernumber, callback) {
    pool.query('Select controlnumber From orders Where ordernumber = ?', [ordernumber], function(err, result) {
      if (!err) {
        if (result.length == 0) {
          callback(true);
        }
        else {
          callback(false);
        }
      }
    });
  }

在db.needsImported的回调函数中,collection[i]变为undefined。这让我很生气,所以我制作了一个小示例文件,看看是否有我无法从回调函数内部访问参数的原因。它按预期工作,只推动偶数。这是示例:

var nums = [];
var collection = [1,2,3,4,5,6,7,8,9,10];

displayValue(collection, function() {

});
console.log(nums);

function displayValue(col, callback) {
  for(var i = 0; i < col.length; i++) {
    sleep(col[i] * 500, function() {
      console.log('Count: ' + col[i]);
      if (col[i] % 2 == 0) {
        nums.push(col[i]);
      }
    });
    callback();
  }
}

function sleep(time, callback) {
  var stop = new Date().getTime();
  while(new Date().getTime() < stop + time) {
      ;
  }
  callback();
}

我希望有人能帮助我理解我做错了什么。

如果您在预期 collection[i] 未定义的地方 console.log(i),您可能会更清楚地看到问题所在。

for 循环中发生的事情是遍历数组并触发多个异步任务。当循环完成时,i 的值为 2。i 是一个封闭变量,您的回调可以访问,但请记住这里的异步时间,您的 needsImported 回调都被调用 after 你的 for 循环已经完成,所以自然地,collection[2] 是未定义的。要修复它,您可以去掉索引并改用 Array.forEach

function loopOrders(collection, callback) {
    var answersReturned = 0;
    collection.forEach(function(item, index) {
        needsImported(item.ordernumber, function(answer) {
            console.log('index:', index);
            if (answer) {
                OrdersListToImport.push(item);
            }
            if (++answersReturned == collection.length) {
                callback();
            }
        });
    });
}

另请注意,如果您确实需要在回调中跟踪索引,您可以像我上面那样将其作为 forEach 回调中的第二个参数接收。

再注意一下:)这段代码有一个重大缺陷:

needsImported: function(ordernumber, callback) {
    pool.query('Select controlnumber From orders Where ordernumber = ?', [ordernumber], function(err, result) {
      if (!err) {
        if (result.length == 0) {
          callback(true);
        }
        else {
          callback(false);
        }
      }
    });
  }

如果确实发生 err,您将忽略它,但更糟糕的是,您没有调用回调。令人困惑的错误将从中出现。在节点中将错误变量作为回调的第一个参数是常见的做法,因此在成功的情况下,您会这样做 callback(null, true).