为何函数需等待password赋值?Node.js异步查询问题排查
问题原因与解决方案
核心问题是userExists函数虽然标记了async,但内部采用回调式的数据库查询,没有返回Promise,导致await无法等待异步操作完成,直接拿到undefined。
修正步骤
1. 重构db.js的userExists函数,改为返回Promise
把回调式的pool.query包装成Promise,让await能正确等待结果:
const userExists = async (req, res) => { return new Promise((resolve, reject) => { pool.query('Select * from "Users" Where useremail=$1', [req.body.userName], (error, results) => { if (error) { // 数据库出错时抛出错误 return reject(error); } if (results.rows.length === 0) { // 处理用户不存在的情况,避免后续访问rows[0]报错 return reject(new Error('User does not exist')); } // 查询到用户时返回哈希密码 resolve(results.rows[0].password); }); }); };
2. 修正index.js的/auth路由,添加错误处理
await可能抛出数据库错误或用户不存在的错误,需要用try/catch捕获,同时处理bcrypt.compare的潜在错误:
app.post('/auth', async (req, res) => { try { // 等待数据库查询完成,拿到哈希密码 const password = await db.userExists(req, res); bcrypt.compare(req.body.password, password, (err, result) => { if (err) { // 处理bcrypt加密错误 return res.status(500).send('Server error'); } if (result) { console.log('passwords are the same'); req.session.userid = req.body.userName; currentUser = req.body.userName; db.getAccountPage(req, res, req.body.userName); } else { res.render('pages/signIn', {wrongPassword: "Incorrect Password"}); } }); } catch (err) { // 捕获用户不存在或数据库错误,返回对应提示 res.render('pages/signIn', {wrongPassword: "User not found or server error"}); } });
关键说明
- 标记
async的函数如果没有返回Promise或内部没有await,默认会返回一个值为undefined的resolved Promise,这就是你拿到password = undefined的原因。 - 把回调式异步操作包装成Promise后,
await才能正确等待异步任务完成,拿到预期的返回值。 - 必须处理用户不存在的场景,否则当数据库无匹配结果时,
results.rows[0]为undefined,访问.password会导致程序崩溃。
内容的提问来源于stack exchange,提问作者Grriped
相关产品推荐
相关产品推荐

