javascript - Node.JS 等待每个并行 mysql 查询完成
问题描述
我需要以下方面的帮助:我有4 个 MySQL 查询,我希望并行运行,但在继续主函数之前必须完成所有查询;这四个查询获取数据的不同部分(它们的结构不同并访问不同的表),然后在 main 函数中使用。也就是说,我使用了 async.parallel(甚至尝试添加await关键字),但在async.parallel中调用最终回调之前仍然结束。我什至考虑过集群和工作线程,但是每个查询函数都彼此不同。
async.parallel中的函数是 MySQL 连接查询,形式如下:
connection.query(q, function(err, res) {
if(err) {
callback(err, [])
} else {
// do something
callback(null, res)
}
})
每个函数都有不同的形状,为了简洁起见,这只是一个简化的形式。函数示例:
async main_function() {
await async.parallel({
"1": function(callback) { conn.query(q1, function(...) { console.log("1"); callback(null, 1) }) },
"2": function(callback) { conn.query(q2, function(...) { console.log("2"); callback(null, 2) }) },
"3": function(callback) { conn.query(q3, function(...) { console.log("3"); callback(null, 3) }) },
"4:" function(callback) { conn.query(q4, function(...) { console.log("4"); callback(null, 4) }) }
}, function(err, results) { /*final callback; do something*/ console.log("Finished"); })
console.log("Continuing");
//continue
}
预期输出:
3
2
4
1
Finished
Continuing
实际输出:
Continuing
3
2
4
1
Finished
如果还有其他方法(即使没有 async.parallel),我也愿意接受。稍后我可能会在函数和程序的其他部分中使用多个不同的并行 MySQL 查询,因此使用 async.parallel 之类的参数化形式非常有用。
Javascript 是单线程的意味着诸如“检查查询是否完成的 while 循环”之类的解决方案不起作用。这个 main_function 会经常被调用,所以分叉会导致问题。
编辑:Jakub 的解决方案相当简单,因为在我的程序中如下所示:
async main_function() {
await Promise.all([
new Promise((resolve, reject) => {
connection.query(q1 , function (error, result) {
if (error != null) {
console.log("mysql query error", error);
return reject(error);
} else {
console.log("1");
resolve(result);
}
})
}),
new Promise((resolve, reject) => {
connection.query(q1 , function (error, result) {
if (error != null) {
console.log("mysql query error", error);
return reject(error);
} else {
console.log("2");
resolve(result);
}
})
}), ... // Two more times
]).then((values) => {
data[0] = values[0];
data[1] = values[1];
data[2] = values[2];
data[3] = values[3];
}).catch(function (err) { console.log(err); });
console.log("Continuing"); //continue
}
这现在非常粗糙,如果有人想为未来的程序员建议更清洁/更好的解决方案,请继续。
解决方案
这些查询函数是基于回调的(从您的代码来看),您可以对它们进行承诺:
import { promisify } from 'utils';
async main_function() {
const res = await Promise.all([
promisify(conn.query)(q1),
promisify(conn.query)(q2),
// all your other queries
]);
console.log("Continuing");
//continue
}
推荐阅读
- markdown - Markdown 无法在内联代码段内创建链接
- python - 如何使用 VBA 指定打印机?
- django - DRF 嵌套序列化程序无法更新嵌套数据
- php - codeigniter DOMPDF 显示空白屏幕,没有错误,html 生成正确但 pdf 不生成
- unix - 我使用 nohup 运行了一个脚本,其中调用了 3 个下标
- fortran - 不同的程序结果取决于程序的链接方式
- python - 当输入为 DataFrame 时,使用索引数组在 GridSearchCV 中定义折叠
- typescript - Firebase 云函数使用 onCall 返回处理后的数据
- ios - 如何将 HMAC 中的密钥作为 HEX Swift iOS 传递
- javascript - 无法绑定到“chartType”,因为它不是“画布”的已知属性