我必须检查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) {
//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;否则,返回null
即使在这里查看了许多类似的主题,我也没有找到解决问题的方法。
答案 0 :(得分:2)
您的操作“将所有foreignKeys
与所有tables
进行比较”可以写在一行中。
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 */);
但是,根据foreignKeys
和tables
的数量以及QueryFunction
的复杂程度,这可能会对数据库服务器造成巨大压力。如果有10个表和1000个外键,这将尝试对数据库服务器并行运行10,000个查询。这不是一件明智的事情。
使用SQL处理这些情况。您可以决定对10,000个项目运行一个查询,而不是对每个事物运行10,000个查询。或10个查询,每个查询1000件事。显然,两者都比处理10,000个请求的数据库服务器更好。
例如,这一步返回了table_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需要如何显示。
您有多个表来检查同一外键的事实也令人担忧,这通常表明数据库设计不佳。
答案 1 :(得分:0)
很少有常见的入门错误。让我们从棘手的问题开始,它在异步上下文中的for循环中使用var
关键字。如您所见,这只会返回10
,而不返回1, 2, 3
。
for (var i=0; i < 10; i++) {
setTimeout(() => console.log(i), 100);
}
在这种情况下,修复很容易-只需使用let
,它的范围就与var
不同,并且可以按您的预期工作。
for (let i=0; i < 10; i++) {
setTimeout(() => console.log(i), 100);
}
第二个是异步上下文-for循环在您在QueryFunction返回的promise中执行异步上下文之前结束。如果您可以使用新版本的Node.js,那么async/await
是您的救星,只需将函数标记为async
并拥有
const result = await QueryFunction(tables[index], key, foreignKeys[key])
但是请注意-一旦在Promise / Asynchronous上下文中有了某些内容,您基本上就无法返回到同步上下文。因此,您的所有逻辑需求都必须意识到您处于异步状态。这基本上意味着所有结果都是承诺,您将需要then
或await
它们。它不是bug或其他东西,它的行为,您需要依靠它。
答案 2 :(得分:0)
您可以执行类似打印控制台中的消息或写入文件的操作,可以获得视觉效果。
如果要获得结果,请使用“等待”。