node.js async/await 与 MySQL 一起使用

IT技术 javascript mysql node.js asynchronous
2021-02-26 08:58:38

我需要同步所有结果并附加到带有 async/await 关键字(如 c#)的字符串。

我是 node.js 的新手,我无法将这种新语法应用于我的代码。

var string1 = '';
var string2 = '';
var string3 = '';
var string4 = '';

DatabasePool.getConnection(function(err, connection) {

        connection.query(query,function (err, result) {
            if (err){};
            string1 = result;
        });

        connection.query(query,function (err, result) {
            if (err){};
            string2 = result;
        });     

        connection.query(query,function (err, result) {
            if (err){};
            string3 = result;   
        });

        connection.query(query,function (err, result) {
            if (err){};
            string4 = result;
        }); 

       //I need to append all these strings to appended_text but  
       //all variables remain blank because below code runs first.
       var appended_text = string1 + string2 + string3 + string4;
});
6个回答

如果您碰巧在 Node 8+ 中,则可以利用util.promisify()节点 mysql来利用本机

不要忘记调用它,bind()这样this就不会搞砸了:

const mysql = require('mysql'); // or use import if you use TS
const util = require('util');
const conn = mysql.createConnection({yourHOST/USER/PW/DB});

// node native promisify
const query = util.promisify(conn.query).bind(conn);

(async () => {
  try {
    const rows = await query('select count(*) as count from file_managed');
    console.log(rows);
  } finally {
    conn.end();
  }
})()
对于typescript:const query: (arg1: string, arg2?: string[])=>Promise<unknown> = promisify(db.query).bind(db);
2021-04-16 08:58:38
感谢您添加绑定的说明。我花了很长时间试图弄清楚为什么我在 promisify 上遇到了问题。
2021-04-17 08:58:38
非常感谢您提供正确绑定方式的提示
2021-04-17 08:58:38
mysql-async-simple 包为你做这件事。
2021-04-20 08:58:38
如果我必须为查询函数提供 2 个参数,typescript会给出错误“预期的 1 个参数”。我使用了两个参数,因为查询字符串包含一个?. 有没有办法避免在单个查询字符串中附加第二个参数?
2021-04-26 08:58:38

使用 mysql2 数据包。它具有Promise包装器,因此您可以这样做:

async function example1 () {
  const mysql = require('mysql2/promise');
  const conn = await mysql.createConnection({ database: test });
  let [rows, fields] = await conn.execute('select ?+? as sum', [2, 2]);
}
使用 await conn.end() 执行查询后不要忘记结束连接;或者更好地使用池而不是像 createPool 和结束池这样的连接。
2021-05-05 08:58:38
这应该是公认的答案,因为 mysql 现在已弃用,mysql2 至今仍在维护并支持异步
2021-05-08 08:58:38
这是上级的答案...圣牛Mysql2是要快得多比MySQL,并提供吨的东西的MySQL不一样,Promise和压缩和预处理语句。
2021-05-12 08:58:38
我在这里有点困惑,我是否需要为每个查询创建到 MySQL 的连接或将 conn 设为全局并在所有路由中使用?
2021-05-12 08:58:38

假设您使用的是基于Promise的 ORM,您可以执行以下操作

async function buildString() {
  try {
    const connection = await DatabasePool.getConnection();
    const string1 = await connection.query(query);
    const string2 = await connection.query(query);
    const string3 = await connection.query(query);
    const string4 = await connection.query(query);

    return string1 + string2 + string3 + string4;
  } catch (err) {
    // do something
  }
}

任何 promise 都可以通过放在await调用前面来与 async/await 一起使用但是,请注意函数必须在async函数“包装器”中使用。您需要处理try/catch块中的错误

我还想指出,这 4 个查询不是同时运行的。为此,您仍然需要使用 Promise.all。

我使用 mysql 包。我认为这不是基于Promise的?我应该使用哪个 mysql 包?
2021-04-17 08:58:38
请注意, await 只能在异步方法中使用。
2021-04-23 08:58:38
有很多,所以我认为您可能需要花一些时间来探索权衡。你可能会遇到的一些是:objection.js、bookshelf、sequelize
2021-04-28 08:58:38
谢谢@WilcoBakker。我实际上只是在编辑我的答案:)
2021-05-08 08:58:38
如何从查询中获取返回的行值而不是获取字符串?
2021-05-11 08:58:38

如果您想使用 mysql(也称为 mysqljs),如果您不想使用包装器,则必须做一些工作。但这很容易。下面是连接函数的样子:

const mysql = require('mysql')

var my_connection = mysql.createConnection({ ... })

async function connect()
{
    try
    {
        await new Promise((resolve, reject) => {
            my_connection.connect(err => {
                return err ? reject(err) : resolve()
            })
        })
    }
    catch(err)
    {
        ...handle errors...
    }
}

connect()

如您所见,await 将知道如何处理Promise。您创建此类并在回调实现中使用解析/拒绝函数。这就是它的全部内容,真的,所以除非您经常访问数据库,否则使用包装器可能会有点多。

或者使用 mysql-async-simple

https://www.npmjs.com/package/mysql-async-simple

const { makeDb } = require('mysql-async-simple');
const mysql = require("mysql");
 
const connection = mysql.createConnection({
    host: process.env.HOST,
    user: process.env.USER,
    password: process.env.PASSWORD,
    database: process.env.DB
});
const db = makeDb();
await db.connect(connection);
 
try {
    const users = await db.query(connection, 'SELECT * FROM users');
} catch (e) {
    // handle exception
} finally {
    await db.close(connection);
}