我正在尝试从mysql数据库中移动大量数据(大于最大查询大小的数量),并且需要通过块中的循环来运行它来执行此操作。我遇到的问题是即使在50个记录的小样本中,我也总是缺少大约一半,因为在循环结束之前似乎连接已经关闭。我遇到问题的代码段如下:
for(var j = 0; j < maxNum; j+=increment){
// populates the array that can be used to find the mods that have been purchased
console.log("START = " + j + " END = " + (j+increment));
con.query("SELECT * FROM sometable WHERE id BETWEEN " + j
+ " AND " + (j + increment), function(err, rows, fields){
if(!err){
console.log("ROWS = " + rows.length);
for(var a = 0; a < rows.length; a++){
arrayOfObjs.push(rows[a]);
console.log(rows[a].ID);
// If the inner loop is at the end and the while loop is about to end this cycle
if( (a + 1 == rows.length) && ((userCounter + increment - 1) > maxNum)) {
// Loop through all the user objects and if it has records, add it to that item
for(var b = 0; b < arrayOfUsers.length; b++){
arrayOfUsers[b].objs = returnObjById(b, arrayOfMods);
// If the loop is ending
if(b+1 == arrayOfUsers.length){
done1 = true;
// temp force close
shutDown()
}
}
}
}
}
else{
console.log(err);
}
})
}
maxNum应该表示整个表中的用户总数,增量将是块的大小。 returnObjs函数不调用任何东西,是一个对功能没有影响的简单开关。 shutDown函数是一个mysql连接端,带有一个用于回调的process.exit。该函数是在脚本完成之前结束的,但由于我是Node的新手,我不知道如何调整它以确保不会继续发生这种情况。任何建议都会受到赞赏,因为这部分是作为学习Node的一种方式完成的,因为用我熟悉的语言做起来并不困难。
答案 0 :(得分:0)
我在这里看到两个可能的问题。
首先,conn.query()
可能是一个异步函数(通过查看我在那里看到的回调函数)。这意味着节点不会等待在继续执行之前调用回调,导致在调用第一个conn.query()
回调之前执行所有第一次循环迭代。
我建议你看看这个优秀的图书馆:async。它对异步操作有很大帮助,例如在你想要在开始另一次迭代之前等待回调的情况下。就此而言,async.series()
功能可能会有所帮助。
其次,当第三个shutdown()
循环的最后一次迭代完成时,您调用for
似乎会自动发生,但您仍处于第一个和第二个{{1}的第一次迭代中}循环。这意味着for
永远不会递增,j
也不会递增。应在第一个a
循环的最后一次迭代结束时调用shutdown()
函数。
编辑:我在第三个for
循环之前忽略了您的if
。我不确定for
检查的目的是什么,但如果它阻止在(userCounter + increment - 1) > maxNum
或a
未达到最大值时调用第三个循环,那么你可以丢弃我的第二点。虽然异步问题仍然存在,但很可能是导致问题的原因。