如何在节点js服务器的for循环中管理近5000条记录?

时间:2016-12-27 16:46:48

标签: javascript mysql node.js mongodb

我使用NodeJS创建了一个服务器。 MySQL中有一个数据库,其中有近5000个用户。我必须阅读mysql数据库并更新并在MongoDB数据库中创建一个日志。我为此实现了一个代码。 https://gist.github.com/chanakaDe/aa9d6a511070c3c78ba3ebc018306ad8

这是问题所在。在这个代码中,在第50行,我添加了这个值。

userArray[i].ID]

这是来自for循环的用户ID,我需要使用该ID更新mysql表。 for循环块中的所有代码。但是我收到了这个错误。

  

TypeError:无法读取未定义的属性“ID”

因此我将这些值分配给顶部的变量。见第38和39行。

var selectedUserID = userArray[i].ID;
                var selectedUserTelephone = userArray[i].telephone;

当我这样使用时,没有错误。但用户ID未更新。最近2个值具有相同的用户ID。

这是什么解决方案?

2 个答案:

答案 0 :(得分:1)

这是一个与异步操作期间范围和提升变量概念相关的一般JavaScript问题。

var a = 0;

function doThingWithA () {
  console.log(a)
}

for (var i=0; i<1000; i++) {
  a++;
  setTimeout(function () {
    doThingWithA();
  }, 10);
}

在此示例中,“a”将始终以值1000记录。原因是setTimeout(模仿慢速数据库操作)需要时间并且在此期间(在日志发生之前)“a”增加由于for循环不等待setTimeout完成,因此为1000。

最佳解决方案是使用“异步”模块。

pool.getConnection(function (err, connection) {
  connection.query(query, function (err, users) {
    async.eachSeries(users, function (user, next) {
      async.parallel([
        function updateUserStatus (cb) { /* your current code */ },
        function updateUserAccount (cb) { /* current code for this */ }
      ], next);
    }, function (err) { console.log('finished for all users!') })
  });
});

您也可以使用承诺。这是node.js中的典型异步问题。从读取代码开始,您认为每个操作都是串行运行,而在节点中,每个输入/输出(例如db调用)都会被触发,但您的代码会继续运行,如上面的for循环示例所示。

答案 1 :(得分:0)

有一个名为 ES6-promise-pool

的酷库

https://www.npmjs.com/package/es6-promise-pool

所以它有并发选项 喜欢:

var count = 0
var promiseProducer = function () {
  if (count < 5) {
    count++
    return delayValue(count, 1000)
  } else {
    return null
  }
}

var pool = new PromisePool(promiseProducer, 3)

pool.start()
  .then(function () {
    console.log('Complete')
  })