Node.js/Express中如何使用async/await实现mysql2 Promise操作
mysql2 配合 Promise/async/await 正确实现方案
报错核心原因
- 第一次报错:默认引入
mysql2包创建的连接是回调风格,query方法不会返回Promise,直接使用await调用就会触发对应报错。 - 改成引入
mysql2/promise后报query不存在:Promise版本的createConnection是异步方法,直接同步调用导出的是处于pending状态的Promise对象,不是实际的数据库连接实例,自然找不到query方法。
正确实现步骤
优先推荐使用连接池方式,比单连接性能更好、自带连接复用和异常重连,不需要提前等待连接建立,导出即可直接使用。
第一步:修改数据库连接配置文件
const mysql = require('mysql2/promise'); // 数据库连接参数 const dbConfig = { host: 'localhost', user: 'root', password: 'letsgetkinky', database: 'nodelogin' }; // 创建连接池并导出 const pool = mysql.createPool(dbConfig); module.exports = pool;
第二步:改造登录校验中间件
注意Promise风格的query返回值是[结果集, 字段元数据]的数组结构,和回调风格的参数顺序不同;另外要加错误捕获,避免数据库异常直接导致服务崩溃,同时修正原回调代码里模板字符串误用单引号的bug。
const db = require('../../database'); async function checkIfLogedIn(req, res, next) { const membershipnumber = req.session.membershipno; // 未登录直接进入后续中间件 if (!req.session.loggedin) { return next(); } try { // 解构获取查询结果,参数化查询避免SQL注入 const [results] = await db.query( 'SELECT * FROM customers WHERE membershipnumber = ?', [membershipnumber] ); if (results.length > 0) { req.user = { // 原代码用单引号包裹模板字符串,无法解析变量,需改为反引号 name: `${results[0].first_name} ${results[0].last_name}`, membershipnumber: results[0].membershipnumber, customer_id: results[0].id }; } next(); } catch (error) { res.status(500).send('数据库查询错误:' + error.message); } } module.exports = checkIfLogedIn;
其他注意事项
- 如果一定要使用单连接而非连接池,需要在服务启动阶段先
await mysql.createConnection(dbConfig)拿到实际连接实例,再挂载路由、启动服务,不能直接同步导出createConnection的调用结果。 - 如果不想切换引入包为
mysql2/promise,也可以在原有回调风格的连接实例上调用.promise()方法拿到Promise包装实例,比如const promiseDb = db.promise(),后续用promiseDb.query()即可支持async/await写法。 - Promise风格下所有数据库操作都要放在
try/catch块中捕获异常,不要把错误抛到全局导致进程退出。
内容的提问来源于stack exchange,提问作者j bel
相关产品推荐
相关产品推荐

