res.send()在function代码在节点js中执行之前执行

我是节点js的新手。 在我的应用程序中,我正在查询MySql数据库并使用节点j处理和查看处理结果。 如果我的查询返回空数据,然后我做另一个查询,并执行该过程。 但是我的res.send(finaldate)代码在function过程完成之前就被执行了。 如何解决这个问题。 res.send(finaldata)在“do require stuff for finaldata”之前执行。

var finaldata ={}; //first query var result = connection.query('myquery', function(err, data_rows){ if(!err){ //second //doing one more Query for some other records from DB (second query) connection.query('myquery', function(err, rows, fields){ if(0 < rows.length){ finaldata = //do require stuff for finaldata } else{ //third //do the second query with some condition connection.query(queryText, function(err, rows, fields) { finaldata = //do require stuff for finaldata }) } res.send(finaldata); }); } }); 

您只需将res.send()调用移动到第二个查询的callback中,如下所示:

 connection.query('myquery', function(err, rows, fields){ if(0 < rows.length){ finaldata = //do require stuff for finaldata res.send(finaldata); //<---If data } else{ //third //do the second query with some condition connection.query(queryText, function(err, rows, fields) { finaldata = //do require stuff for finaldata res.send(finaldata); // <--- If no data }) } 

欢迎来到NodeJS和asynchronous计算的世界!

问题是res.send在第二个connection.query完成之前执行。 为了弥补这一点,你把res.send放在callback中。

 var result = connection.query('myquery', function(err, data_rows) { if (!err) { //second //doing one more Query for some other records from DB (second query) connection.query('myquery', function(err, rows, fields) { if (0 < rows.length) { // do something res.send( /* send something*/ ); } else { //third //do the second query with some condition connection.query(queryText, function(err, rows, fields) { // do something res.send( /*send something*/ ); // 2nd res.send }) } }); } }); 

在if和else条件中使用res.send

 var finaldata = {}; var result = connection.query('myquery', function(err, data_rows) { if (!err) { connection.query('myquery', function(err, rows, fields) { if (0 < rows.length) { finaldata = //some value res.send(finaldata); } else { connection.query(queryText, function(err, rows, fields) { finaldata = //some value res.send(finaldata); }) } }); } }); 

虽然接受的答案肯定是正确的,但是我个人发现在查询命令中包含一个Promise(),在语法上更容易:

 connection.queryPromiser = function(sql, args) { return new Promise(function(resolve, reject) { connection.query( sql, args, function(err, results, fields) { if (err) { reject(err); } else { resolve( {"results": results, "fields": fields} ); } } ); }); }; 

那么你可以完成你的res.send像这样:

 connection.queryPromiser("SELECT id FROM users WHERE username = ?", [ "Sami" ]) .then(function(data) { if (data.results.length) { return connection.queryPromiser("SELECT * FROM user_data WHERE user_id = ?", [ data.results[0].id ]) .then(function(data) { if (data.results.length) { return data.results[0]; } else { return "no user_data"; } }); } else { return "no user"; } }).then(res.send) .catch(console.error); 

从技术上讲,任何你可以用promise来完成的事情都可以通过callback来完成。 我只是觉得把事情封装成承诺更容易一些。