Node.js中MySQL查询校验管理员身份的函数返回undefined问题排查
问题根因
你的代码存在两个核心错误,导致返回值不符合预期:
- 异步调用的返回值无法被外层函数接收
db.query是异步API,你传入的回调函数会在数据库查询完成后才触发执行,而外层的isAdmin函数执行到db.query语句后就直接结束运行了,没有等待回调执行,且isAdmin本身没有定义返回值,自然返回undefined。你在回调函数中写的return只会把值返回给db.query的内部逻辑,和外层的isAdmin没有任何关联。 - forEach 的返回无法跳出遍历也无法返回上层
就算忽略异步问题改为同步逻辑,forEach中写的return也只会退出当前轮次的遍历回调,既不能终止整个forEach遍历,也不会把值返回给上层的查询回调。同时你的现有逻辑会在匹配第一个管理员后就返回,要是第一个不是直接返回false,后面就算有匹配的uid也不会校验,逻辑本身就存在错误。
修复方案
建议将函数改造为返回Promise的形式,配合async/await调用即可拿到预期的布尔返回值:
function isAdmin(useruid) { return new Promise((resolve, reject) => { // 优化查询语句:直接按uid过滤,不用查全表遍历,性能更高 db.query("SELECT 1 FROM admins WHERE uid = ? LIMIT 1", [useruid], function(err, rows) { if (err) { console.log(err); return reject(err); } if (rows.length > 0) { console.log("[is admin] Found admins!"); resolve(true); } else { console.log("[is admin] User is not admin!"); resolve(false); } }) }) }
调用方式有两种可选:
方式1:使用.then链式调用
isAdmin(要校验的用户uid).then(isAdminFlag => { // 此处拿到布尔值isAdminFlag处理业务逻辑 }).catch(err => { // 处理数据库查询报错 })
方式2:使用async/await(更推荐,代码可读性更高)
// 必须在async修饰的函数内部调用 async function yourBusinessFunc() { try { const isAdminFlag = await isAdmin(要校验的用户uid); // 此处拿到布尔值isAdminFlag处理业务逻辑 } catch (err) { // 处理数据库查询报错 } }
内容的提问来源于stack exchange,提问作者HAZZE
相关产品推荐
相关产品推荐

