我来自PHP后台,其中SQL查询被阻止。
我通常的设置是制作一个try, catch
块来处理表更新期间可能发生的任何可能的错误。我想将这种逻辑转移到nodejs,但是它的异步特性使它变得很麻烦。看一下示例代码:
var httpServer = Https.createServer(httpsOptions, function (request, response) {
try {
//many queries in if-else, switch statements
if(something){
mysqlConnection.query(query,[],function(err, result){});
}else{
//many queries will follow
if(somethingelse){
mysqlConnection.query(query2,[],function(err, result){});
}else{
mysqlConnection.query(query3,[],function(err, result){});
if(andsoon){}
}
}
response.writeHead(200, { "Content-Type": "text/plain" });
response.end("Got it.");
console.log("Response successful");
}catch(error){
console.error(error);
response.writeHead(400, { "Content-Type": "text/plain" });
response.end("Error.");
}
}).listen(8000);
因此,response.end()
将在查询执行之前触发,因此我会在知道查询是否成功之前发送消息。我可以将response.end()
代码包装在回调中,但是正在执行许多查询,因此现在我必须跟踪到目前为止已执行了多少个查询。情况变得更糟,1个if-else控制流仅需要1个查询,而其他一些则需要10个查询,因此在代码完成时进行跟踪会产生疯狂的开销。
这都不是最佳的工作流程。如果您拥有复杂的查询系统,并且只想在所有查询都已执行(或失败)后才发送响应,该怎么办?
答案 0 :(得分:0)
您已从.query调用中放入了null回调。那是你的问题。
mysqlConnection.query(query,[],function(err, result){});
xxxxxxxxxxxxxxxxxxxxxxxx
JavaScript继续运行显示的之后的下一条语句,而无需等待查询完成。您知道仅当.query方法调用您的回调函数时,查询才完整(或遇到错误)。
因此,您需要执行类似的操作。
mysqlConnection.query(query,[],function(err, result){
if (err) throw Error(err);
//many queries will follow
if(somethingelse){
...
}
});
像您需要的一系列查询最终以一组荒谬的深度嵌套的回调函数结束。但是请不要失望:Javascript的Promise模式可为您解决此问题,并为您提供简洁的代码。使用npm's promise-mysql package。并编写这样的代码。
mysqlConnection.query(query,[])
.then (function(mySqlConnection) {
if (somethingelse)
return mysqlConnection.query(query2,[])
else
return mysqlConnection.query(query3,[])
})
.then (function(mySqlConnection) {
return mysqlConnection.query(query4,[])
})
.then (function(mySqlConnection) {
response.writeHead(200, { "Content-Type": "text/plain" });
response.end("Got it.");
})
.catch (function(err)) {
/* failure somewhere ! */
});
您有一系列的then函数,最后有个陷阱。 Promise子系统为您隐藏了所有回调调用,而是通过这种方式进行组织。 (请注意,我没有调试此示例代码。)
您必须弄清楚此Promise stuff才能成功编程sql / nodejs。起初这是违反直觉的(至少在我学习时是对我来说)。但这值得您的努力。专家提示:如果要在调试器中逐步执行此类代码,请自由使用“逐步进入”。