Node.js 在nodejs的循环中使用异步函数?
我必须检查foreignKey是否存在,但我不能使用异步查询函数进行循环Node.js 在nodejs的循环中使用异步函数?,node.js,asynchronous,Node.js,Asynchronous,我必须检查foreignKey是否存在,但我不能使用异步查询函数进行循环 function checkAllFK(tables, foreignKeys) { let index = -1; for (var key in foreignKeys) { index++; QueryFunction(tables[index], key, foreignKeys[key]) .then(result => { if(result == null) {
function checkAllFK(tables, foreignKeys) {
let index = -1;
for (var key in foreignKeys) {
index++;
QueryFunction(tables[index], key, foreignKeys[key])
.then(result => {
if(result == null) {
//here, if result is null, that's mean the foreignKey doesn't exist, then, we have to stop the loop and return false;
return false;
}
else if(index == (tables.length - 1)) {
//here, that's mean we are at the end of the loop, and we doesn't break it with the previous if, that's mean all foreignKey exist, then, we return true;
return true;
}
}
问题是,在第一次迭代结束时,退出函数,返回的结果仅取决于第一次迭代:如果在第一次迭代中满足if条件,则返回false;如果在第一次迭代中不满足if条件,则返回null
即使在这里看过许多类似的话题,我也没有找到解决问题的方法。常见的begginer错误很少。让我们从棘手的一个开始,它在异步上下文中的for循环中使用
var
关键字。如您所见,这将只返回10
s,而不是1、2、3
for(变量i=0;i<10;i++){
setTimeout(()=>console.log(i),100);
}
您可以像在控制台中打印消息或写入文件一样,获得可视化结果
如果您想获得结果,请使用“等待”。您的操作“对照所有表检查所有外键
”可以写在一行中
function checkAllFK(tables, foreignKeys) {
return Promise.all(tables.map(t => Promise.all(foreignKeys.map(k => QueryFunction(t, k))));
}
此函数返回一个承诺,该承诺在所有查询完成时解析,因此您可以像这样调用它
checkAllFK(tables, foreignKeys)
.then(/* success */)
.catch(/* error */);
但是,根据外键
和表的数量以及查询功能
的复杂程度,这可能会给数据库服务器带来巨大的压力。如果有10个表和1000个外键,这将尝试对数据库服务器并行运行10000个查询。这不是一件明智的事情
SQL是用来处理这些情况的。您可以决定为10000件事情运行一个查询,而不是为每件事情运行10000个查询。或者10个查询,每个查询1000件事情。这两种方法显然都比用10000个请求重击数据库服务器要好
例如,这将一步返回表_1
中不存在的所有外键
SELECT
k.key_column
FROM
foreign_keys k
LEFT JOIN table_1 t ON t.key_column = k.key_column
WHERE
t.key_column IS NULL
这取决于您在QueryFunction
中执行的操作,实际的SQL需要是什么样子
您有多个表要检查相同的外键这一事实也令人担忧,这通常表明数据库设计很差。尝试研究异步等待和承诺。如何在QueryFunction周围包装一个承诺,以便在循环中使用等待时从异步函数调用它?首先不要在SQL表上逐个编写此类循环。这是非常低效的。SQL已经为此设置了操作,这些东西可以在一个SQL语句中找到。第三个问题是,OP最好使用一个使用联接或EXISTS操作的SQL语句,而不是从客户端逐个检查键。这确实不是一个答案,更适合作为注释。当你获得更多的声誉,你将能够添加评论…是的,非常多。至少使用Promise.all
,如果可能,最好是单个查询。回答得好!