NodeJS异步函数VerifyUserByUsernamePassword返回值始终为undefined求助
问题:异步函数返回undefined,调用函数无法获取结果
我是JavaScript(及回调函数)新手,在NodeJS应用中编写了异步函数VerifyUserByUsernamePassword,用于从SQL数据库获取用户数据,该功能正常;随后使用BCrypt验证用户输入密码与存储的appPassword是否匹配,验证也可正常执行。但无论密码匹配成功或失败,向调用函数返回JSON对象时,调用函数中的result始终为undefined,附上异步函数及调用函数代码,寻求解决方法。
原异步函数代码
async function VerifyUserByUsernamePassword(userEmail, password) { const sql = require('mssql') const { configMSSQL } = require("./db.config.js"); if (sql) sql.close(); return await sql.connect(configMSSQL).then(async pool => { // Stored procedure let output_parameter return await pool.request() .input('Email', sql.NVarChar, userEmail) // .output('output_parameter', sql.Int) .execute('API_READ_USER_BY_EMAIL') }).then(async result => { sql.close(); // sql = null; if (result.recordset.length > 0) { const appPassword = result.recordset[0].appPassword; bcrypt.compare(password, appPassword, async function (err, result2) { if (err) { console.log(err); return ({ "message": "failed" }) } if (!result2) { // console.log("result2", result2) return ({ "message": "failed" }) } console.log("result2 was True") return ({ "message": "success", "data": result }) }) } else { console.log("Error retrieving User Records for Login Verification......"); return ({ "message": "failed" }) } }).catch(err => { sql.close(); // ... error checks console.log("Error retrieving User Records for Login Verification", err); return ({ "message": "failed" }); }); }
原调用函数代码
exports.VerifyLogin = async (req, res) => { var errors = [] if (!req.body.email) { errors.push("Credentials Missing"); } if (!req.body.password) { errors.push("Credentials Missing"); } if (errors.length) { res.status(400).json({ "error": errors.join(",") }); return; } var email = req.body.email var password = req.body.password const { VerifyUserByUsernamePassword } = require("../database/mssqldb.js"); await VerifyUserByUsernamePassword(email, password).then(async result => { if (result && result.message === "success") { res.json(result.data); } else { res.json({ "message": "failed", "User Record ": email },); } }).catch(err => { console.log(err); res.json({ "message": "error", "User Record ": email },) }) }
问题原因
核心问题是你用了bcrypt.compare的回调版本,回调函数里的return不会作为外层then回调的返回值。处理SQL查询结果的那个then函数,在执行bcrypt.compare后没有返回任何值,导致整个VerifyUserByUsernamePassword函数最终返回undefined。
async/await基于Promise工作,你需要把bcrypt.compare包装成Promise,或者直接用bcrypt提供的Promise版本。
修正后的代码
异步函数(VerifyUserByUsernamePassword)
// 模块引入放在文件顶部,避免重复加载 const sql = require('mssql'); const { configMSSQL } = require("./db.config.js"); const bcrypt = require('bcrypt'); async function VerifyUserByUsernamePassword(userEmail, password) { try { // 关闭可能存在的旧连接 if (sql) await sql.close(); // 连接数据库并执行存储过程 const pool = await sql.connect(configMSSQL); const result = await pool.request() .input('Email', sql.NVarChar, userEmail) .execute('API_READ_USER_BY_EMAIL'); await sql.close(); if (result.recordset.length > 0) { const appPassword = result.recordset[0].appPassword; // 使用bcrypt.compare的Promise版本,配合await获取结果 const isPasswordMatch = await bcrypt.compare(password, appPassword); if (!isPasswordMatch) { return { "message": "failed" }; } return { "message": "success", "data": result }; } else { console.log("Error retrieving User Records for Login Verification......"); return { "message": "failed" }; } } catch (err) { // 出错时确保关闭连接 if (sql) await sql.close(); console.log("Error retrieving User Records for Login Verification", err); return { "message": "failed" }; } }
调用函数(VerifyLogin)
统一用async/await风格,避免混合.then()让逻辑更清晰:
const { VerifyUserByUsernamePassword } = require("../database/mssqldb.js"); exports.VerifyLogin = async (req, res) => { const errors = []; if (!req.body.email || !req.body.password) { errors.push("Credentials Missing"); } if (errors.length) { return res.status(400).json({ "error": errors.join(",") }); } const { email, password } = req.body; try { const result = await VerifyUserByUsernamePassword(email, password); if (result && result.message === "success") { res.json(result.data); } else { res.json({ "message": "failed", "User Record": email }); } } catch (err) { console.log(err); res.json({ "message": "error", "User Record": email }); } }
额外优化点
- 模块引入放在文件顶部,避免函数内重复加载,提升性能且减少潜在问题。
- 尽量统一
async/await和.then()的使用风格,优先用async/await让代码更易读。 - 数据库连接关闭逻辑放在
try/catch中,确保无论成功失败都能释放连接资源。
内容的提问来源于stack exchange,提问作者Jan
相关产品推荐
相关产品推荐

