Javascript Node.js无法在循环内运行mysql查询
我在mysql中有两个表,希望根据另一个表的结果查询一个表,所以我编写了如下函数Javascript Node.js无法在循环内运行mysql查询,javascript,mysql,node.js,Javascript,Mysql,Node.js,我在mysql中有两个表,希望根据另一个表的结果查询一个表,所以我编写了如下函数 export function getLocations(req, res) { const database = new Database(); database.query('select * from districts') .then(rows => { let appData = []; rows.forEach(row => {
export function getLocations(req, res) {
const database = new Database();
database.query('select * from districts')
.then(rows => {
let appData = [];
rows.forEach(row => {
const new_database = new Database();
new_database.query(`SELECT locations.id,locations.name, IF(subscriptions.id IS NULL,0,1) as subscribed
FROM locations
LEFT JOIN subscriptions
ON (subscriptions.location_id = locations.id AND subscriptions.user_id=1)
WHERE locations.district=?`,row.id)
.then(sub_rows => {
let district=row;
district["locations"]=sub_rows;
appData.push(district);
new_database.close();
}, err => {
return new_database.close().then(() => { throw err; })
})
.catch(err => {
console.log(err);
res.status(500).json("Database Error");
})
});
res.status(200).json(appData); //final result here
database.close()
}, err => {
return database.close().then(() => { throw err; })
})
.catch(err => {
console.log(err);
res.status(500).json("Database Error");
})
}
在这里,我希望基于第一个查询的每一行运行第二个查询。
我得到一个空数组作为结果。我的第一个查询正在正确执行,我记录了日志以查看是否返回了所有行。有什么问题吗?您可以通过使其异步来实现
rows.forEach(async row => {
const new_database = new Database();
await new_database.query(`SELECT locations.id,locations.name, IF(subscriptions.id IS NULL,0,1) as subscribed
FROM locations
LEFT JOIN subscriptions
ON (subscriptions.location_id = locations.id AND subscriptions.user_id=1)
WHERE locations.district=?`,row.id)
.then(sub_rows => {
let district=row;
district["locations"]=sub_rows;
appData.push(district);
new_database.close();
}, err => {
return new_database.close().then(() => { throw err; })
})
.catch(err => {
console.log(err);
res.status(500).json("Database Error");
})
});
您正在执行的操作是I/O,JS是单线程的。这意味着用外行术语来说,它不会等待,它将迭代你的循环,在那里它将发出一个请求,在请求处理过程中有一些等待。您需要告诉JS此事件是异步的。为此,您需要使用async/await
向导
我没有这台机器的环境。它可能有一些错误,但如果有,您可以修复它,请查看以下逻辑
export function getLocations(req, res) {
const database = new Database();
const promises=[];
database.query('select * from districts')
.then(rows => {
let appData = [];
rows.forEach(row => {
promises.push(getAnotherQuery(row));
});
database.close()
}, err => {
return database.close().then(() => { throw err; })
})
.catch(err => {
console.log(err);
res.status(500).json("Database Error");
})
return Promise.all(promises).then(result)=> res.status(200).json(result); //final result here
}
getAnotherQuery=(row)=>{
return new Promise((resolve,reject)=>{
const new_database = new Database();
const appData=[]
new_database.query(`SELECT locations.id,locations.name, IF(subscriptions.id IS NULL,0,1) as subscribed
FROM locations
LEFT JOIN subscriptions
ON (subscriptions.location_id = locations.id AND subscriptions.user_id=1)
WHERE locations.district=?`,row.id)
.then(sub_rows => {
let district=row;
district["locations"]=sub_rows;
appData.push(district);
new_database.close();
resolve(appData);
}, err => {
return new_database.close().then(() => { throw err; })
})
.catch(err => {
console.log(err);
res.status(500).json("Database Error");
})
});
}
也不建议混合使用promises和async await。您能给我一个参考资料来支持您的论点吗@基本上这没有问题,它会工作,但我谈论的是标准,你能给我一个参考,异步/等待和承诺不能一起用作好/坏标准吗?同样,在我回答的第一行,我确实提到这个函数需要异步。@AnoopKrishnan,这个答案会很有效,不幸的是,我找不到任何好的参考来证明我的观点。但如果是我,我更喜欢继续使用Promissions将所有新的Promissions推送到一个数组中,然后您可以将它们全部执行到
Promise.all()
;就性能而言,我认为这会更好,因为如果最后一次选择失败,那么它将不会继续执行其余的选择