Express后端嵌套异步函数返回undefined,如何正确获取最终结果?
问题原因
checkCredentials中调用bcrypt.compare时使用了回调写法,回调内的return result只会把值返回到回调函数本身,无法传递到外层的checkCredentials函数- 没有等待
bcrypt.compare的异步执行结果,checkCredentials会在bcrypt执行完成前就结束运行,该分支下没有明确返回值,所以默认得到undefined
修复方案
修改checkCredentials函数
直接调用bcrypt的Promise版本接口,用await获取对比结果,同时可以合并两次重复的SQL查询,减少数据库开销:
const checkCredentials = async (clientUsername, clientPassword) => { try { // 合并两次SQL查询为一次,同时获取用户名和密码哈希 const queryRes = await pool.query( "SELECT varol_users_dealer_username, varol_users_dealer_hash FROM varol_users_dealers_credentials WHERE varol_users_dealer_username = $1", [clientUsername] ); const dbUser = queryRes.rows[0]; // 用户名不存在直接返回false if (!dbUser) return false; // 直接await获取bcrypt对比结果,不需要回调 const passwordMatch = await bcrypt.compare(clientPassword, dbUser.varol_users_dealer_hash); return passwordMatch; } catch (error) { console.error(error); return false; } }
可选优化:补充路由的异常响应
原路由的catch块只打印错误没有返回响应,容易导致前端请求超时,可以补充异常返回逻辑:
app.post("/login", async(req, res) => { try { const { username, password } = req.body; // 增加参数非空校验,避免无效请求 if (!username || !password) return res.status(400).json({msg: "用户名和密码不能为空"}); let result = await checkCredentials(username, password) console.log("result of checkCredentials:", result); res.json(result); } catch (error) { console.error(error); res.status(500).json({msg: "服务器内部错误"}); } });
内容的提问来源于stack exchange,提问作者momomo
相关产品推荐
相关产品推荐

