javascript - Node.js - 如何使用 MySQL 查询从 for 循环中返回带有数组的回调?
问题描述
我正在尝试在我的 Node.js 应用程序上获取虚拟社区列表,然后使用回调函数返回它。当我用回调调用 getList() 方法时,它返回一个空数组。
const mysqli = require("../mysqli/connect");
class Communities{
getList(callback){
var list = [];
mysqli.query("SELECT * FROM communities", (err, communities) => {
for(let i = 0; i < communities.length; i++){
mysqli.query("SELECT name FROM users WHERE id='"+ communities[i].host +"'", (err, host) => {
list.push({
"id": communities[i].id,
"name": communities[i].name,
"hostID": communities[i].host,
"hostName": host[0].name,
"verified": communities[i].verified,
"people": communities[i].people
});
});
}
callback(list);
});
}
}
new Communities().getList((list) => {
console.log(list);
});
我需要将 for 循环设为异步并在 for 循环结束时调用回调。请让我知道如何做到这一点。谢谢。
解决方案
如果你必须组合多个回调,回调会变得非常丑陋,这就是为什么发明了 Promises 来简化它。要在您的情况下使用 Promise,您必须在查询数据库时首先创建一个 Promise ¹:
const query = q => new Promise((resolve, reject) => mysqli.query(q, (err, result) => err ? reject(err) : resolve(result)));
现在执行多个查询将返回多个 Promise,可以将它们组合Promise.all
为一个 Promise²:
async getList(){
const communities = await query("SELECT * FROM communities");
const result = await/*³*/ Promise.all(communities.map(async community => {
const host = await query(`SELECT name FROM users WHERE id='${community.host}'`);/*⁴*/
return {
...community,
hostName: host[0].name,
};
}));
return result;
}
现在您可以通过以下方式轻松获得结果:
new Communities().getList().then(list => {
console.log(list);
});
继续阅读:
使用 Promise - Google Developers
笔记:
¹:如果您更频繁地这样做,您可能更应该使用原生支持 Promise 的 mysql 库,这样可以节省大量工作。
²:通过请求是并行完成的,这意味着它比一个接一个地完成要快得多(可以使用 for 循环并在其中等待)。
³:那await
是多余的,但我更喜欢保留它以将其标记为异步操作。
⁴:我想这也可以使用一个 SQL 查询来完成,所以如果它对你的用例来说太慢(我怀疑)你应该优化查询本身。
推荐阅读
- magento - 有没有办法在侧边栏中添加主导航的一部分?
- javascript - Angular:一个formControlName中的多个字段,反应形式
- date - 使用 awk 和日期在一行中更改文本文件的 gmt
- web2py - web2py如何在另一个动作/视图上链接网格
- python - 如何释放分配给嵌套 numpy 数组的内存?
- php - 如何防止通过双击提交
- linux - 在 FFMPEG 中选择出站 IP(eth0 或 eth1)
- c++ - 为什么在以下示例中我需要在 block_cache.h 之前包含 block_cache_key.h 和 block.h?
- java - 将Java中的二进制文件读取到特定的“%%EOF”标记?
- php - check id in all tables have the prefix table_