node.js 异步/等待与 MySQL 一起使用

问题描述 投票:0回答:13

我需要同步所有结果,并使用 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;
});
javascript mysql node.js asynchronous
13个回答
100
投票

如果您碰巧在 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();
  }
})()

75
投票

使用mysql2包。它有承诺包装,所以你可以这样做:

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]);
}

13
投票

假设你使用的 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 一起使用。但是,请注意,this 函数必须在
async
函数“包装器”中使用。您需要处理
try/catch
块中的错误。

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


6
投票

如果你想使用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()

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


3
投票

或者使用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);
}


3
投票

正如LeOn - Han Li所述,我进行了一些小的修改,因为我必须处理结果。

var mysql = require('mysql');
const util = require('util');

const conn = mysql.createConnection({
  host     : '127.0.0.1',
  user     : 'user',
  password : 'password',
  database : 'database'
});

const query = util.promisify(conn.query).bind(conn);

let result = async function() {
    var userCourse = [];
    try {
        const rows = await query('select * as count from file_managed');
    } finally {
        conn.end();
        return userCourse;
    }
};

result()
.then(value => {
    console.log(value)
});

2
投票

您可以像这样使用

promise-mysql
包:

const mysql = require('promise-mysql')

const getDbConnection = async () => {
  return await mysql.createConnection({
    host: process.env.HOST,
    user: process.env.USER,
    password: process.env.PASSWORD,
    database: process.env.DB
  })
}

const getUsers = async () => {
  const db = await getDbConnection()
  const users = await db.query("SELECT * FROM users")
  await db.end()
  return users
}


1
投票

您必须确保您使用的 mysql 库支持 Promises,这是

async
/
await
所要求的,或者使用像 Bluebird 的
promisifyAll
这样的工具来包装库。

async function appendedText() {
  const connection = await DatabasePool.getConnectionAsync();
  const [string1, string2, string3, string4] = await [
    connection.query(query1),
    connection.query(query2),
    connection.query(query3),
    connection.query(query4),
  ];
  return string1 + string2 + string3 + string4;
}

请注意,调用

appendedText()
实际上会返回一个 Promise,而不是一个值。

appendedText().then(appended_text => {});

1
投票

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);
}


0
投票

您似乎使用了mysqljs,这不是一个承诺的基础库。所以使用这个库你无法达到你想要的效果。因此,您可以做的是使用基于承诺的库,例如 Sequelize 或其他评论建议的那样:

使用 Bluebird 的 promisifyAll 之类的工具来包装库。

我对包装的东西不太了解,所以我所做的就是切换到续集。


0
投票

我们可以在 mysql.connect 中实现 Promise,而不是使用 utilpromise/mysql

var con = require('mysql');

var mysql = con.createConnection({
    host: "localhost",
    user: "root",
    password: "pass",
    database: "test"
});

async function asyncAwait(req, res) {
    var promise1;
    mysql.connect((err) => {
        promise1 = new Promise((resolve, reject) => {
            console.log('Mysql: Connected');
            resolve(response.write(uc.upperCase('Connected\n')));
        });
        promise1
            .then(() => {
             //Implement the logic here
            })
            .catch(error => {
                console.log(error)
            });
    })
}
await asyncAwait();

0
投票

就我而言,我必须创建一个辅助函数,它是一个承诺并解决如下

const mysqlQuery = async (connection, queryConfig) => {
    const config = { ...queryConfig, timeout: 4000 }

   return new Promise((resolve, reject) => {
     return connection.query(config, function (error, results, fields) {
        if (error) {
            reject(error);
        }
        resolve(results);
      });
   })
}

现在我可以轻松使用上面的内容了

    const response = await mysqlQuery(connection, {
       sql: 'SELECT * FROM `user`',
    });

     console.log(response)

连接是你的mysql连接,如下所示

    var connection = mysql.createConnection({
        host,
        user, //
        password, //
        database,
        port
    })
   
    connection.connect(async (err) => {
          if(err){
             //connection error
             return;
           }

         //successifull connection
     })

0
投票

我正在使用以下mysql2:

const express = require('express');
const cors = require('cors');
const mysql = require("mysql2/promise");
const fetch = require('node-fetch');

所以它仍然不适用于上面提到的代码。我会尝试续集,看看是否有效。

© www.soinside.com 2019 - 2024. All rights reserved.