【问题标题】:Code running in wrong order after added connection pool (async/await needed?)添加连接池后代码运行顺序错误(需要异步/等待?)
【发布时间】:2021-04-24 09:36:24
【问题描述】:

我有一个 NodeJS API,它使用“正常连接”到 MYSQL 数据库并且运行良好,但我遇到了断开连接的问题。 我现在已经实现了池化并且它正在工作,但是由于连接的新性质,现在一些代码似乎出现了故障。

我从未使用过 async/await,因为我对编码很陌生,但我已经尝试在此处执行此操作以获得所需的响应。 我几乎已经在控制台日志中查看了它的运行顺序,而不是得到“1,2,3”,我得到的是“2,3,1”,这显然会给我错误的结果,因为我在继续之前需要获取查询数据。

有人可以展示如何让这个等待系统工作吗? 第一部分从用户那里获取 MAC 和 ID,然后检查我的数据库中是否已经存在。如果是,那么它会更新最近登录的日期时间。如果没有,则添加 MAC。

问题是我没有得到关于 mac 是否存在的回复,所以它总是“假”,因此 mac 不断被添加,因为它没有等待第一个查询结果!

router.post('/updateComp/',verify,async (req,res) => {    
    //console.log(req.params.MAC)
       
    var sqlString = "SET @chemistID = ?; SET @MAC = ?; Call checkMAC(@chemistID,@MAC)";
    try{
        const MAC = req.body.MAC;;
        const compName = req.body.compName;
        var compCount = 0;
        var MACExists = false;
        
        console.log(MAC + " " + compName);
        await connection.query(sqlString,[req.user._id,MAC], (err,rows,fields)=>{
            console.log("Check 1"); 
            if(!err){
                
                rows.forEach(element => {
                
                    if(element.constructor == Array){
                        compCount =  element[0].compCount;
                        MACExists =  element[0].MACExists; 
                        console.log(compCount);                    
                        console.log(MACExists);
                    }
                    else{
                    //array not returned?
                    return res.status(500);
                    }
                })    
                
            }else{
                //sql con error?
                return res.status(500);
            }
            console.log("comcount = " + compCount);
        })
        console.log("Check 2");   
        
        if(compCount == 0 || (compCount < 7 && MACExists == false)){
            //Insert new comp
            var sqlString = "INSERT INTO tblLicense (chemistID,compName,MAC,lastAccess) VALUES (?,?,?,current_timestamp());";
            console.log("Check 3");

                connection.query(sqlString,[req.user._id,compName,MAC], (err,rows,fields)=>{
                    if(!err){
                        console.log("New terminal added for " + req.user._id);
                        return res.status(200).json({
                            Result: true,
                            compAdded: true
                        })

                    }else{
                        console.log("Failed to add new computer to sub " + req.user._id);
                        return res.status(500).json({
                            Result: false,
                            compAdded: false,
                            Comment: "Failed to add new computer to sub"                            
                        })
                    }
                })

        }else{
            if (compCount == 7){
                if(MACExists){
                    return res.status(200).json({
                        Result: true                        
                    })
                }else{
                    return res.status(200).json({

                        Result: false,
                        compAdded: false,
                        Comment: compCount
                    })
                }
                
            }else{
                //Update time of current comp access
                var sqlString = "UPDATE tblLicense SET lastAccess = current_timestamp() WHERE MAC = ? AND chemistID = ?;";

                connection.query(sqlString,[MAC,req.user._id], (err,rows,fields)=>{
                    if(!err){
                        return res.status(200).json({

                            Result: true,
                            compAdded: false
                        })

                    }
                    else
                    {
                        return res.status(500).json({

                            Result: false,
                            compAdded: false                            
                        })
                    }
                })
            }
        }
    } catch (e) {
        // this catches any exception in this scope or await rejection
        console.log(e);
        res.status(500).json({ Result: e });
    }  
});

连接配置:

const mysql = require('mysql');

  var pool = mysql.createPool({    
    host:'localhost',
    user: '1234',
    password: '1234',
    database : '1234',
    multipleStatements: true,
    connectionLimit: 10
});
  
pool.getConnection((err, connection) => {
  if (err) {
      if (err.code === 'PROTOCOL_CONNECTION_LOST') {
          console.error('Database connection was closed.')
      }
      if (err.code === 'ER_CON_COUNT_ERROR') {
          console.error('Database has too many connections.')
      }
      if (err.code === 'ECONNREFUSED') {
          console.error('Database connection was refused.')
      }
  }
  if (connection) connection.release()
  return
})  


module.exports ={
     connection : pool 
} 

【问题讨论】:

  • 检查connection.query 的执行返回了什么。我看到你在做connection.query(param1, param2, callback),通常当你切换到 async/await 意味着你从回调切换到 Promise。要让 await 以您希望的方式工作,connection.query(...params) 需要返回一个 Promise。如果您可以分享 connection.query 的样子,我可以进一步帮助您
  • 感谢@NicolasCastellanos,现在更新

标签: mysql node.js asynchronous connection-pooling


【解决方案1】:

检查 https://github.com/mysqljs/mysql 似乎不会返回 Promise。

您仍然可以通过将 connection.query 包装在 Promise 中来使用 async/await。

这是一个解释如何做到这一点的帖子https://medium.com/wenchin-rolls-around/example-of-using-transactions-with-async-await-via-mysql-connection-pool-9a37092f226f

看起来另一种选择是使用 Bluebird How to promisify a MySql function using bluebird?

【讨论】:

  • 哇...对于这样一个小问题,我的代码只有一个地方看起来很复杂:(谢谢,在实施之前我必须真正理解
  • @GlennAngel 在阅读了很多像你这样的问题后,我写了一个blogpost。有更好的方法。 2021 年不要使用蓝鸟。
猜你喜欢
  • 2020-05-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-06-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多