mysql - Node JS 等待一系列 mysql 查询
问题描述
我正在使用 mysql 和 Node JS 开发一个 RESTful API。我在定义为的选择函数中将查询包装到数据库中:
var mysql = require('mysql');
var db = mysql.createConnection({
host : CONFIG.db_host,
user : CONFIG.db_user,
password : CONFIG.db_password,
database : CONFIG.db_name
});
function select(query, callback, out, args)
{
console.log('Sent query: ' + query);
db.query(query, args, function(err, rows){
if(err) throw err;
return callback(rows, out);
});
};
为了在我的应用程序中实现一个功能,我必须对返回未确定行数 (N) 的数据库表执行查询,并使用在每一行中获得的信息对另一个执行 N 个新查询桌子。
就像是:
function callback(rows, out){
// just to give the idea ...
for(var i=0; i<rows.length; i++)
{
db.select("SELECT * FROM table WHERE col=?", function(rows, out){
out.push(rows);
}, rows[i].col)
}
// wait for all queries ...
console.log(out)
}
out = []
db.select("SELECT * FROM table WHERE col=?", callback, out, col)
异步运行所有查询没有问题,但我必须等待所有查询结束,然后才能返回我的 API 响应。我认为使用 Promises 可能是一种方式,但鉴于未确定的查询数量,我不知道如何实现它。你能帮助我吗?
解决方案
你的主要问题是for
循环。使用它意味着您正在混合同步和异步代码。
如果您需要使用回调模式,我建议您还使用外部库,例如async,它可以更轻松地使用异步迭代模式。像下面这样的东西可能会奏效:
var async = require('async');
conn.query('SELECT * FROM table WHERE col=?', col, function (err, rows) {
async.each(rows, function (row, callback) {
conn.query('SELECT * FROM other_table WHERE col=?', row.col, callback);
}, function () {
// all queries are done
})
});
如果你想使用 Promise,mysql2包提供了与mysql类似的 API ,但支持Promise。使用基于 - 的 API 的有趣之Promise
处在于,您可以使用async/await
(在 Node.js 上>= 7.6
),如果您不喜欢常规 JavaScript 代码的异步特性,这会让您的生活变得更轻松。
因此,在您的情况下,您将能够执行以下操作:
var mysql = require('mysql2/promise');
async function main () {
var conn = await mysql.createConnection({
host : CONFIG.db_host,
user : CONFIG.db_user,
password : CONFIG.db_password,
database : CONFIG.db_name
});
var [rows] = await conn.query('SELECT * FROM table WHERE col=?', col);
var out = [];
for (var row of rows) {
var result = await db.query('SELECT * FROM other_table WHERE col=?', row.col);
out.push(result);
}
// all queries are done
}
main();
推荐阅读
- asp.net-core-mvc - 身份服务器 4 使用 FrontChannelLogoutUri 从所有客户端注销不起作用
- amazon-web-services - AWS Lambda 调用 Fargate 任务
- reactjs - ANT 设计推拉混淆
- azure-devops - 无法在远程服务器(VM)中为 Azure 发布管道安装代理(持续部署)
- javascript - “点击 1 获得 1,点击 2 获得 2”
- http - 如何充当中间人服务器在客户端和远程服务器之间添加 HTTP 标头?
- python - 反正有没有在正则表达式的搜索功能中使用变量?
- psql - 我怎样才能回滚 psql -f 命令?
- android - 如何在视图绑定中的活动中获取回收者视图当前项目文本值
- typescript - I'm getting a confusing legend in Highcharts (angular-highcharts)