NodeJS中执行MySQL查询时如何将值推入数组并使用查询返回记录数
问题原因
你遇到的是Node.js异步IO的执行顺序问题,并不是回调函数无法操作外部变量:mysql.db.query是异步方法,调用后会立刻执行后续外层代码,而回调函数会等到数据库查询完成才触发。如果你在外层读取errors数组或者记录数变量的时机早于回调触发时间,拿到的自然是还没被修改的初始值。
解决方案
方案1:将依赖查询结果的逻辑全部移入回调内部
所有需要用到查询记录数、errors数组的判断和业务逻辑,都写在回调函数内部,保证查询完成后才执行对应逻辑:
const errors = [] const userExistence = "SELECT COUNT(*) AS countEmail FROM users WHERE Email = ?"; mysql.db.query(userExistence, [email], (err, result) => { // 优先处理查询错误 if (err) { console.log('查询异常:', err) return res.status(500).json({ msg: '服务器内部错误' }) } if (result[0].countEmail !== 0) { errors.push({ msg: '该邮箱对应的账户已存在' }); } // 所有依赖查询结果、errors数组的逻辑都放在这里执行 if (errors.length > 0) { return res.status(400).json({ errors }) } // 后续业务逻辑(如写入新用户、其他关联查询等)也放在此处 // ... res.end(); });
方案2:用Promise+async/await改写,避免回调嵌套
如果不想多层回调嵌套,可以把查询方法封装为Promise,用async/await语法把异步逻辑写成同步写法的形式,更易维护:
// 封装mysql查询为Promise格式 const query = (sql, params) => { return new Promise((resolve, reject) => { mysql.db.query(sql, params, (err, result) => { if (err) return reject(err) resolve(result) }) }) } // 在async函数中使用await调用查询 async function handleRegister() { const errors = [] const userExistence = "SELECT COUNT(*) AS countEmail FROM users WHERE Email = ?"; try { // await等待查询完成才执行后续代码 const result = await query(userExistence, [email]) if (result[0].countEmail !== 0) { errors.push({ msg: '该邮箱对应的账户已存在' }); } // 此处可以直接正常使用errors数组、查询结果做条件判断 if (errors.length > 0) { return res.status(400).json({ errors }) } // 后续业务逻辑 // ... res.end() } catch (err) { console.log('查询异常:', err) res.status(500).json({ msg: '服务器内部错误' }) } } // 调用异步函数 handleRegister()
内容的提问来源于stack exchange,提问作者Garamvolgyi Soma
相关产品推荐
相关产品推荐

