在发送HTTP响应之前捕获mysql错误

时间:2019-01-24 11:57:50

标签: mysql node.js asynchronous promise synchronous

我来自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个查询,因此在代码完成时进行跟踪会产生疯狂的开销。

这都不是最佳的工作流程。如果您拥有复杂的查询系统,并且只想在所有查询都已执行(或失败)后才发送响应,该怎么办?

1 个答案:

答案 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。起初这是违反直觉的(至少在我学习时是对我来说)。但这值得您的努力。专家提示:如果要在调试器中逐步执行此类代码,请自由使用“逐步进入”。