【问题标题】:node.js mysql pool connection with async/ awaitnode.js mysql 池连接与 async/await
【发布时间】:2018-07-15 13:21:29
【问题描述】:

有没有办法以async/ await 语法使用从mysqljs/mysql 库中获取的pool.getConnection()

这个想法是有一个方法,它返回一个连接,该连接可以在释放它之前在具有各种外键约束(顺序查询)的写入查询中传递,同时可能从池中获取更多连接,以达到以下目的各种读取查询(并行)。

【问题讨论】:

  • 是的,有一种方法,将“getConnection”包装在返回承诺的函数中。然后使用 await 等待它。
  • 这不使用原生的Promise API,但它允许你使用async/await:promise-mysql

标签: mysql node.js async-await mysqljs


【解决方案1】:

分享我的工作示例:

我用这个Promisified MySQL middleware for Node.js

阅读这篇文章Create a MySQL Database Middleware with Node.js 8 and Async/Await

这是我的 database.js

var mysql = require('mysql'); 

// node -v must > 8.x 
var util = require('util');


//  !!!!! for node version < 8.x only  !!!!!
// npm install util.promisify
//require('util.promisify').shim();
// -v < 8.x  has problem with async await so upgrade -v to v9.6.1 for this to work. 



// connection pool https://github.com/mysqljs/mysql   [1]
var pool = mysql.createPool({
  connectionLimit : process.env.mysql_connection_pool_Limit, // default:10
  host     : process.env.mysql_host,
  user     : process.env.mysql_user,
  password : process.env.mysql_password,
  database : process.env.mysql_database
})


// Ping database to check for common exception errors.
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
 })

// Promisify for Node.js async/await.
 pool.query = util.promisify(pool.query)



 module.exports = pool

你必须升级 node -v > 8.x

你必须使用 async 函数才能使用 await。

示例:

   var pool = require('./database')

  // node -v must > 8.x, --> async / await  
  router.get('/:template', async function(req, res, next) 
  {
      ...
    try {
         var _sql_rest_url = 'SELECT * FROM arcgis_viewer.rest_url WHERE id='+ _url_id;
         var rows = await pool.query(_sql_rest_url)

         _url  = rows[0].rest_url // first record, property name is 'rest_url'
         if (_center_lat   == null) {_center_lat = rows[0].center_lat  }
         if (_center_long  == null) {_center_long= rows[0].center_long }
         if (_center_zoom  == null) {_center_zoom= rows[0].center_zoom }          
         _place = rows[0].place


       } catch(err) {
                        throw new Error(err)
       }

【讨论】:

【解决方案2】:

队友。我不知道为什么,但我尝试了一整天,但无法让它工作。在您的 cmets 的帮助下,我再次尝试了,它当然可以工作。

db.js:

const pool = mysql.createPool(config);

exports.getConnection = () => {
    return new Promise((resolve, reject) => {
        pool.getConnection(function (err, connection) {
            if (err) {
                return reject(err);
            }
            resolve(connection);
        });
    });
};

someWhereElse.js:

const db = require('./db');

const wrappingFunction = async () => {
    const connection = await db.getConnection();
    console.log(connection);
};
wrappingFunction();

【讨论】:

    【解决方案3】:

    似乎手动实现承诺是一个更好的选择。 只是分享我在代码中使用的内容 -

    const mysql = require('mysql');
    const config = require('config');
    
    const pool = mysql.createPool(config.get('db.mysql'));
    
    module.exports = {
        checkConnection: () => {
            return new Promise((resolve, reject) => {
                pool.getConnection((err, conn) => {
                    if (err) {
                        return reject(err);
                    }
                    resolve(conn.release());
                });
            });
        },
        pool,
        closeConnection: () => pool.end(),
    };
    

    【讨论】:

      【解决方案4】:

      以前的答案(使用 util.promisify)对我不起作用,只能手动实现 Promise:

      功能:

      async function removeItem (id)  {
      
      return new Promise( (resolve) => {
          pool.query('DELETE FROM table_name WHERE id=' + id, (error) => {
                resolve ({result: !error});
              });
          }); 
      } 
      

      用法:

      const app = express();
      const mysql = require('mysql');
      const pool = mysql.createPool({
                  connectionLimit: 10,
                  host: 'localhost',
                  user: 'login',
                  password: 'pass',
                  database: 'dbname'
              });
      
      
      
      app.post("/:id", async (req, res) => {
              const answer = await itemRemove(id);
              res.send(answer);
          });
      

      【讨论】:

        【解决方案5】:

        当然,你必须先承诺,从node 8.0.0 现在你可以这样做:

        const util = require('util');
        
        async function doSomething() {
             const getConnectionAsync = util.promisify(pool.getConnection);
           try {
               const result = await getConnectionAsync('MASTER');
            }catch(err) {
               console.log('Oh no');
            }
        } 
        

        如果由于某种原因你不能使用 node 8 或更高版本,还有其他方法可以承诺它,比如http://bluebirdjs.com/docs/api/promise.promisify.html

        【讨论】:

        • 这不起作用,它向我显示以下错误:``` TypeError [ERR_INVALID_ARG_TYPE]:“原始”参数必须是函数类型。 ```
        【解决方案6】:

        只是分享我一直在我的代码中使用的东西:

        //Filename: MySQL.js    
        
        module.exports = {
            connect: function ()
            {
                return new Promise((resolve, reject) => {
        
                let pool = Mysql.createPool({ //require configfile.js or just put connection detail here
                        connectionLimit: config.mysql.connectionLimit,
                        host: config.mysql.host,
                        user: config.mysql.user,
                        password: config.mysql.password,
                        database: config.mysql.database
                    });
        
                    pool.getConnection((err, connection) =>
                    {
                        try
                        {
                            if (connection)
                            {
                                resolve({"status":"success", "data":"MySQL connected.", "con":pool});
                                connection.release();
                            }
                        }
                        catch (err)
                        {
                            reject({"status":"failed", "error":`MySQL error. ${err}`});
                        }
                        resolve({"status":"failed", "error":"Error connecting to MySQL."});
                    });
                });
            }
        }
        

        然后每当您需要调用与 MySQL 的连接时

        //Filename: somefile.js
        
        const useMySQL = require('./path/to/MySQL');
        
        module.exports = {
        
            getSomething: function () {
                return new Promise(async (resolve) => {
        
                    try
                    {
                        let connection = await useMySQL.connect();
                        con = connection.con;
        
                        //Do some query here, then
                        resolve(`Send some result/handle error`);
                    }
                    catch (err)
                    {
                        //Handle error if any, log, etc, and eventually
                        resolve(err);
        
                    }
                });
            }
        

        希望这会有所帮助。

        【讨论】:

          猜你喜欢
          • 2017-10-15
          • 1970-01-01
          • 2013-09-01
          • 2019-01-29
          • 2019-09-22
          • 2018-05-28
          • 2013-08-20
          • 2013-10-01
          • 1970-01-01
          相关资源
          最近更新 更多