You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.05 13:54:34