在nodejs中对集合项运行查询

时间:2015-05-09 15:02:52

标签: javascript node.js node-mysql

所以我很难过,似乎无法掌握正在发生的事情。我有一个接受一系列订单的函数。

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功能如下:

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]变为未定义。这让我很生气,所以我制作了一个小样本文件,看看是否有一个原因我无法从回调函数中访问一个参数。它按预期工作,只推动偶数。这是样本:

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();
}

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

1 个答案:

答案 0 :(得分:0)

您可能会更清楚地看到如果您希望console.log(i)未明确定位collection[i]的{​​{1}},问题是什么。

你的for循环中发生的事情是你在迭代数组并启动多个异步任务。当循环结束时,i的值为2. i是一个可以被回调访问的闭合变量,但请记住这里的异步时序,你的needsImported回调都被调用< em>在你的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,则忽略它,但更糟糕的是,您没有调用回调。将会出现令人困惑的错误。节点中的常见做法是将err var作为回调的第一个参数提供,因此在成功的情况下,您可以执行此操作callback(null, true)