如何在Node.js SQL异步回调函数中给外部变量赋值并正确返回
问题根本原因
sql.execute是异步执行方法,传入的回调函数会等到SQL查询完成后才触发执行,但原函数不会等待异步操作完成,会直接执行return admin语句返回初始的null值,自然拿不到校验结果。同时你赋值的_this.admin和函数返回的admin是两个独立变量,二者没有关联,也不会改变返回值。
解决方案
方案1:回调函数改造
首先修改校验模块代码:
module.exports = { checkAdmin: function(username, callback){ sql.execute(sql.format('SELECT * FROM tbl_admins'), (err, result, fields) => { if (err) { logger.error(err.message); return callback(err, false); } // 直接判断是否存在匹配用户名,无需额外遍历生成数组 const isAdmin = result.some(element => element.Username === username); callback(null, isAdmin); }) } }
Express调用逻辑修改:
Admin.checkAdmin(req.body.username, (err, isAdmin) => { if (err || !isAdmin) { console.log("Wrong") return res.send({ message: 'Access denied' }); } // 权限校验通过后的业务逻辑写在这里 });
方案2:Promise + async/await 实现(更推荐,代码更易维护)
校验模块改造为返回Promise:
module.exports = { checkAdmin: function(username){ return new Promise((resolve, reject) => { sql.execute(sql.format('SELECT * FROM tbl_admins'), (err, result, fields) => { if (err) { logger.error(err.message); return reject(err); } const isAdmin = result.some(element => element.Username === username); resolve(isAdmin); }) }) } }
Express路由改造为异步逻辑,调用时用await接收结果:
// 路由处理函数前添加async关键字 app.post('你的接口路径', async (req, res) => { try { const isAdmin = await Admin.checkAdmin(req.body.username); if (!isAdmin) { console.log("Wrong") return res.send({ message: 'Access denied' }); } // 权限校验通过后的业务逻辑 } catch (err) { res.status(500).send({message: '服务端错误'}); } })
额外优化建议
现在的SQL会查询整张管理员表,数据量大时性能很差,建议修改SQL为条件查询,直接匹配用户名:
SELECT 1 FROM tbl_admins WHERE Username = ?
查询时传入username作为参数,只要返回结果长度大于0就是管理员,无需遍历全部结果,性能提升非常明显。
内容的提问来源于stack exchange,提问作者CDOGamer
相关产品推荐
相关产品推荐

