【问题标题】:catch mysql errors before sending HTTP response在发送 HTTP 响应之前捕获 mysql 错误
【发布时间】:2019-06-18 03:48:57
【问题描述】:

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

这一切都不是最佳的工作流程。如果您有一个复杂的查询系统,并且您希望仅在所有查询都执行(或失败)后才发送响应,您会怎么做?

【问题讨论】:

    标签: mysql node.js asynchronous promise synchronous


    【解决方案1】:

    您在 .query 调用中放置了空回调。那是你的问题。

    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 函数,最后有一个 catch 。 Promise 子系统为您隐藏了所有回调调用,而是以这种方式组织它。 (请注意,我没有调试此示例代码。)

    你必须弄清楚这个Promise stuff才能成功编写sql / nodejs。起初它是违反直觉的(至少在我学习它的时候对我来说是这样)。但这值得你努力。专业提示:如果您在调试器中单步执行此类代码,请随意使用 Step Into。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-02-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多