节点 MySql 多个查询的回调
Node MySql Callback for Multiple Queries
我 运行 在尝试创建逻辑以将行添加到我在 MySql 数据库上创建的新 table 时遇到问题。添加一行时,我需要查询数据库 4 次以检查其他行,然后将正确的值添加到新行。我正在使用 node.js 和 mysql 模块来完成此操作。在将 I 运行 编码为障碍时,代码在插入新行之前不会等待 4 个查询完成,然后每次都会为找到的值提供 0 值。经过一些研究,我意识到回调函数是有序的,看起来像这样:
var n = 0;
connection.query("select...", function(err, rows){
if(err) throw err;
else{
if(rows.length === 1) ++n;
}
callback();
});
function callback(){
connection.query("insert...", function(err){
if(err) throw err;
});
}
注意:select 查询只能 return 一项,因此 if 条件不应影响此问题。
只有一个查询等待的回调函数对我来说很清楚,但是对于多个查询等待我有点迷茫。我唯一的想法是创建另一个变量,该变量在调用回调之前递增,然后传入回调函数的参数。然后在回调中,可以将查询封装在一个 if 语句中,条件是该变量等于需要调用的查询数,在这里我的目的是 4。我可以看到这个工作,但不确定这种情况是否已经有内置解决方案,或者是否已经开发了其他更好的解决方案。
您需要 async
(https://github.com/caolan/async)。你可以用这个模块做一个非常复杂的逻辑。
var data = {} //You can do this in many ways but one way is defining a global object so you can add things to this object and every function can see it
firstQueryFunction(callback){
//do your stuff with mysql
data.stuff = rows[0].stuff; //you can store stuff inside your data object
callback(null);
}
secondQueryFunction(callback){
//do your stuff with mysql
callback(null);
}
thirdQueryFunction(callback){
//do your stuff with mysql
callback(null);
}
fourthQueryFunction(callback){
//do your stuff with mysql
callback(null);
}
//This functions will be executed at the same time
async.parallel([
firstQueryFunction,
secondQueryFunction,
thirdQueryFunction,
fourthQueryFunction
], function (err, result) {
//This code will be executed after all previous queries are done (the order doesn't matter).
//For example you can do another query that depends of the result of all the previous queries.
});
根据 Gesper 的回答,我建议使用异步库,但是,我可能会建议并行使用 运行(除非第一个查询的结果用作第二个查询的输入)。
var async = require('async');
function runQueries(param1, param2, callback) {
async.parallel([query1, query2, query3(param1, param2), query4],
function(err, results) {
if(err) {
callback(err);
return;
}
var combinedResult = {};
for(var i = 0; i < results.length; i++) {
combinedResult.query1 = combinedResult.query1 || result[i].query1;
combinedResult.query2 = combinedResult.query2 || result[i].query2;
combinedResult.query3 = combinedResult.query3 || result[i].query3;
combinedResult.query4 = combinedResult.query4 || result[i].query4;
}
callback(null, combinedResult);
});
}
function query1(callback) {
dataResource.Query(function(err, result) {
var interimResult = {};
interimResult.query1 = result;
callback(null, interimResult);
});
}
function query2(callback) {
dataResource.Query(function(err, result) {
var interimResult = {};
interimResult.query2 = result;
callback(null, interimResult);
});
}
function query3(param1, param2) {
return function(callback) {
dataResource.Query(param1, param2, function(err, result) {
var interimResult = {};
interimResult.query3 = result;
callback(null, interimResult);
});
}
}
function query4(callback) {
dataResource.Query(function(err, result) {
var interimResult = {};
interimResult.query4 = result;
callback(null, interimResult);
});
}
Query3 显示了参数 'passed through' 对查询函数的使用。
我相信有人可以向我展示一种更好的组合结果的方法,但这是迄今为止我想到的最好的方法。使用临时对象的原因是,传递给回调的 "results" 参数是一个结果数组,很难确定哪个结果用于哪个查询。
祝你好运。
我 运行 在尝试创建逻辑以将行添加到我在 MySql 数据库上创建的新 table 时遇到问题。添加一行时,我需要查询数据库 4 次以检查其他行,然后将正确的值添加到新行。我正在使用 node.js 和 mysql 模块来完成此操作。在将 I 运行 编码为障碍时,代码在插入新行之前不会等待 4 个查询完成,然后每次都会为找到的值提供 0 值。经过一些研究,我意识到回调函数是有序的,看起来像这样:
var n = 0;
connection.query("select...", function(err, rows){
if(err) throw err;
else{
if(rows.length === 1) ++n;
}
callback();
});
function callback(){
connection.query("insert...", function(err){
if(err) throw err;
});
}
注意:select 查询只能 return 一项,因此 if 条件不应影响此问题。
只有一个查询等待的回调函数对我来说很清楚,但是对于多个查询等待我有点迷茫。我唯一的想法是创建另一个变量,该变量在调用回调之前递增,然后传入回调函数的参数。然后在回调中,可以将查询封装在一个 if 语句中,条件是该变量等于需要调用的查询数,在这里我的目的是 4。我可以看到这个工作,但不确定这种情况是否已经有内置解决方案,或者是否已经开发了其他更好的解决方案。
您需要 async
(https://github.com/caolan/async)。你可以用这个模块做一个非常复杂的逻辑。
var data = {} //You can do this in many ways but one way is defining a global object so you can add things to this object and every function can see it
firstQueryFunction(callback){
//do your stuff with mysql
data.stuff = rows[0].stuff; //you can store stuff inside your data object
callback(null);
}
secondQueryFunction(callback){
//do your stuff with mysql
callback(null);
}
thirdQueryFunction(callback){
//do your stuff with mysql
callback(null);
}
fourthQueryFunction(callback){
//do your stuff with mysql
callback(null);
}
//This functions will be executed at the same time
async.parallel([
firstQueryFunction,
secondQueryFunction,
thirdQueryFunction,
fourthQueryFunction
], function (err, result) {
//This code will be executed after all previous queries are done (the order doesn't matter).
//For example you can do another query that depends of the result of all the previous queries.
});
根据 Gesper 的回答,我建议使用异步库,但是,我可能会建议并行使用 运行(除非第一个查询的结果用作第二个查询的输入)。
var async = require('async');
function runQueries(param1, param2, callback) {
async.parallel([query1, query2, query3(param1, param2), query4],
function(err, results) {
if(err) {
callback(err);
return;
}
var combinedResult = {};
for(var i = 0; i < results.length; i++) {
combinedResult.query1 = combinedResult.query1 || result[i].query1;
combinedResult.query2 = combinedResult.query2 || result[i].query2;
combinedResult.query3 = combinedResult.query3 || result[i].query3;
combinedResult.query4 = combinedResult.query4 || result[i].query4;
}
callback(null, combinedResult);
});
}
function query1(callback) {
dataResource.Query(function(err, result) {
var interimResult = {};
interimResult.query1 = result;
callback(null, interimResult);
});
}
function query2(callback) {
dataResource.Query(function(err, result) {
var interimResult = {};
interimResult.query2 = result;
callback(null, interimResult);
});
}
function query3(param1, param2) {
return function(callback) {
dataResource.Query(param1, param2, function(err, result) {
var interimResult = {};
interimResult.query3 = result;
callback(null, interimResult);
});
}
}
function query4(callback) {
dataResource.Query(function(err, result) {
var interimResult = {};
interimResult.query4 = result;
callback(null, interimResult);
});
}
Query3 显示了参数 'passed through' 对查询函数的使用。
我相信有人可以向我展示一种更好的组合结果的方法,但这是迄今为止我想到的最好的方法。使用临时对象的原因是,传递给回调的 "results" 参数是一个结果数组,很难确定哪个结果用于哪个查询。
祝你好运。