node.js async/await 与 MySQL 一起使用
Posted
技术标签:
【中文标题】node.js async/await 与 MySQL 一起使用【英文标题】:node.js async/await using with MySQL 【发布时间】:2017-10-15 17:02:20 【问题描述】:我需要同步所有结果并附加到带有 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;
);
【问题讨论】:
刚刚检查,您使用的是支持异步/等待的节点版本,对吗? 是的最新版本。 【参考方案1】:假设你使用的 ORM 是基于 Promise 的,你可以做这样的事情
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
通过将await
放在调用前面,任何promise 都可以与async/await 一起使用。但是,请注意 this 函数必须在 async
函数“包装器”中使用。您需要处理try/catch
块中的错误。
我还想指出,这 4 个查询不是同时运行的。你仍然需要为此使用 Promise.all。
【讨论】:
注意 await 只能在异步方法中使用。 谢谢@WilcoBakker。我实际上只是在编辑我的答案:) 我使用mysql包。我认为这不是基于promise的?我应该使用哪个mysql包? 有很多,所以我认为您可能需要一些时间来探索权衡。你可能会遇到的一些是:objection.js、bookshelf、sequelize 如何从查询中获取返回的行值而不是获取字符串?【参考方案2】:您必须确保您使用的 mysql 库支持 async
/await
所需的 Promises,或者使用像 Bluebird's 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 => );
【讨论】:
你真的可以像这样使用 await 来模仿 Promise.all 吗?任何想法我可以在哪里找到更多信息,因为我的快速谷歌搜索返回了非常复杂的方法。 @adam-beck,它工作了一段时间......不过现在它需要一个Promise.all()
。见这里:***.com/questions/34382710/…【参考方案3】:
使用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]);
【讨论】:
这是最好的答案......圣牛 Mysql2 比 mysql快得多,并且提供了大量 mysql 没有的东西,比如 promises、压缩和准备好的语句。 使用 await conn.end() 执行查询后不要忘记结束连接;或者更好地使用池而不是像 createPool 和 end pool 这样的连接。 这应该是公认的答案,因为 mysql 现在已弃用,mysql2 至今仍在维护并支持异步 我有点困惑,我需要为每个查询创建与 MySQL 的连接还是将 conn 设为全局并在所有路由中使用?https://npmcompare.com/compare/mysql,mysql2
--> mysql2
是一个更好的包,而且它有更多意义的完整错误消息,这个比较不会告诉【参考方案4】:
您似乎使用了mysqljs,它不是基于承诺的库。所以你不能使用这个库来实现你想要的。所以你可以做的是使用一个基于承诺的库,比如Sequelize,或者按照评论的建议:
使用 Bluebird 的 promisifyAll 之类的工具来包装库。
我对包装的东西不太了解,所以我所做的就是切换到续集。
【讨论】:
【参考方案5】:如果您恰好在 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();
)()
【讨论】:
感谢关于添加绑定的说明。我花了太长时间试图弄清楚为什么我在使用 Promisify 时遇到问题。 非常感谢有关正确绑定方法的提示 如果我必须为查询函数提供 2 个参数,打字稿会给出错误“预期 1 个参数”。我使用了两个参数,因为查询字符串包含?
。有没有办法避免在单个查询字符串中附加第二个参数?
对于打字稿:const 查询:(arg1: string, arg2?: string[])=>Promise如果您想使用 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。您创建此类并在回调实现中使用解析/拒绝函数。这就是它的全部内容,真的,所以使用包装器可能有点多,除非你经常访问你的数据库。
【讨论】:
【参考方案7】:或者使用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);
【讨论】:
【参考方案8】:您可以像这样使用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
【讨论】:
【参考方案9】:正如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)
);
【讨论】:
【参考方案10】:我们可以在 mysql.connect
中实现 promise,而不是使用 util 或 promise/mysqlvar 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();
【讨论】:
以上是关于node.js async/await 与 MySQL 一起使用的主要内容,如果未能解决你的问题,请参考以下文章
Node.js 7 的 async await 终于来了,不过怎么觉得没啥用
Node.js回调地狱及使用Promiseasync和await函数的解决方法