我使用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。
这是什么解决方案?
答案 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')
})