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

Node.js Express调用userLogin返回undefined问题排查

问题根因

你所有尝试都拿不到值的核心问题有3个:

  • userLogin本身是普通同步函数,没有任何显式返回值,JS中无return的函数默认返回undefined。你在client.query的回调里写的return signedInDetails,只是回调函数自己的返回值,根本传不到外层userLogin的调用方,相当于你写的return完全没作用到外层。
  • 你之前试的Promise、async/await写法逻辑完全错了:只是把本来就返回undefined的userLogin调用结果包了一层,resolve的还是undefined,当然拿不到正确值。setTimeout等2秒更是碰运气,既解决不了函数返回值的问题,也没法保证2秒内查询一定完成,甚至你查询完就调用client.end()关了数据库连接,等再久也没用。
  • /userSignUp路由里的res.redirect写在了数据库查询回调外面,数据库操作还没跑完就已经返回响应跳转了,就算后续查到值也没地方用。
修复步骤

1. 改造userLogin为异步函数,直接返回Promise结果

不要用回调写法写异步逻辑,改成async/await形式,把查询结果直接return出去:

async function userLogin(cookies){
    const HashQuery = {
      text: 'select * from users where session_id = $1',
      values: [cookies]
    }
    // 等待数据库查询结果,pg客户端v7以上原生支持promise,直接await即可
    const res = await client.query(HashQuery);
    if(res.rows.length === 0){
      return false;
    }
    // session_id是唯一字段,查询结果最多1条,不需要用map遍历
    const targetUser = res.rows[0];
    if(parseInt(cookies) === parseInt(targetUser.session_id)){
        return {
          userid: targetUser.user_id,
          signinstatus: true
        }
    }
    return false;
    // 删掉原来的client.end(),数据库连接要全局复用,不能查一次就关
}

2. 改造/userSignUp路由,等待所有异步操作执行完再响应

把路由处理函数改成async形式,所有数据库操作、userLogin调用都加await,等所有逻辑走完再执行redirect:

app.post('/userSignUp', async (req, res, next) => {
    const checkQuery = {
      text: 'select * from users where user_name = $1',
      values: [req.body.uName]
    }
    const insertQuery = {
       text: 'INSERT INTO users(f_name, l_name, user_name, password, session_id) VALUES($1, $2, $3, $4, $5)',
       values: [req.body.fName, req.body.lName, req.body.uName, req.body.pw, req.cookies.hash_an_app]
    }

    try {
      const checkRes = await client.query(checkQuery);
      if (checkRes.rows.length === 0){
        await client.query(insertQuery);
        // 这里await拿结果,不会再是undefined
        const abc = await userLogin(req.cookies.hash_an_app);
        console.log('登录信息:', abc);
      }else{
        console.log("用户名已存在");
      }
      // 所有异步逻辑执行完再跳转
      res.redirect('/user/hello') 
    } catch (err) {
      next(err); // 错误统一交给Express错误中间件处理
    }
});
额外注意事项
  • 绝对不要在单次查询结束后调用client.end():数据库连接应该在服务启动时初始化一次,全局复用,每次查完就关会导致后续所有数据库请求直接报错。
  • 所有依赖异步操作结果的逻辑,必须写在await之后,不要写到异步回调外面,否则会出现逻辑先执行、异步结果还没返回的时序问题。
  • 你原来根路由app.get('/')里调用userLogin的地方也要加await,否则同样拿不到返回值。

内容的提问来源于stack exchange,提问作者Deke

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 01:18:25