Node.js调用async函数Promise时username初始化前访问报错排查
问题原因
代码存在两个核心错误,直接触发运行报错:
- 执行顺序与变量访问逻辑错误:
grabinfo函数中先执行res.render渲染逻辑,此时username变量还未通过后续的await user()查询赋值,且const声明的变量存在暂时性死区,声明前访问会直接抛出ReferenceError: Cannot access 'username' before initialization错误。 - Promise逻辑不完整:
user函数内封装的数据库查询逻辑,遇到查询报错时仅打印日志,既没有调用reject抛出错误,查询无匹配结果时也没有做任何resolve/reject处理,会导致Promise状态悬停,触发未捕获Promise拒绝的警告。
修复方案
调整执行顺序,补全Promise的状态处理逻辑,增加错误捕获,修复后代码如下:
async function user(req, res) { let key = req.cookies['cookie'] // 提前处理cookie不存在的情况 if (!key) return '' return new Promise((resolve, reject) => { connection.query('SELECT * FROM accounts WHERE `key` = ?', [key], (error, results, fields) => { if (error) { console.log(error) // 出错时reject抛出错误 return reject(error) } if (results.length > 0) { resolve(results[0].username) } else { // 无匹配用户时返回空字符串,避免Promise悬停 resolve('') } }); }) } async function grabinfo(req, res) { try { // 先等待异步查询完成拿到用户名,再执行渲染 const username = await user(req, res) res.render('dashboard', { title:'Dashboard', username: username}); } catch (err) { // 捕获错误,返回异常响应,避免未捕获Promise拒绝 res.status(500).send('服务器内部错误') } } module.exports.grabinfo = grabinfo
关键修改点说明
- 调整代码顺序:将
await user()获取用户名的逻辑移到res.render之前,保证渲染时能拿到已赋值的用户名变量。 - 补全Promise状态:数据库报错时调用
reject抛出异常,无匹配查询结果时返回默认空值,避免Promise一直处于pending状态。 - 增加错误捕获:用
try/catch包裹异步逻辑,查询出错时返回友好的错误响应,消除未捕获Promise拒绝的警告。 - 增加前置校验:cookie不存在时直接返回空值,避免无效数据库查询。
内容的提问来源于stack exchange,提问作者Iryi
相关产品推荐
相关产品推荐

