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

Node.js MVC项目连接MySQL查询返回undefined问题排查

问题根源:异步操作的返回值无法同步获取

嘿,这个问题我太熟悉了——你踩中了Node.js异步操作的经典坑!咱们一步步拆解问题:

你的getAllUsers函数里,con.connect和con.query都是异步函数,它们不会阻塞代码执行,而是在后台完成操作后调用传入的回调函数。当你在控制器里调用var arr = UserModel.getAllUsers()时,getAllUsers会立刻执行完毕并返回undefined(因为你没有在函数最外层写return语句),而数据库查询的结果要等回调函数触发时才会生成——这时候控制器早就已经执行完res.send(arr)了,所以arr自然是undefined。

更关键的是:你在回调函数里写的return result,只是把值返回给了回调函数的调用者(也就是MySQL驱动),根本不会把值传递给外层的getAllUsers函数。


解决方案:用回调/Promise/async-await处理异步

方法1:使用回调函数(最基础的异步处理方式)

先修改模型代码,接受一个回调函数作为参数,在查询完成后通过回调传递结果或错误:

exports.getAllUsers = function (callback) {
  con.connect(function (err) {
    if (err) {
      console.log('连接数据库出错:', err);
      // 把错误传给回调
      callback(err, null);
    } else {
      con.query("SELECT * FROM Users", function (err, result, fields) {
        if (err) {
          console.log('查询出错:', err);
          callback(err, null);
        } else {
          // 把查询结果传给回调
          callback(null, result);
        }
      });
    }
  });
}

然后在控制器里通过回调获取结果:

exports.get_all_users = function (req, res) {
  UserModel.getAllUsers(function(err, arr) {
    if (err) {
      // 处理错误,返回500状态码
      return res.status(500).send('数据库查询失败');
    }
    // 成功获取结果,返回给客户端
    res.send(arr);
  });
}

方法2:使用Promise + Async/Await(更现代、易读的方式)

回调嵌套多了容易陷入“回调地狱”,用Promise和async/await可以让代码更像同步逻辑:

先把模型改成返回Promise:

exports.getAllUsers = function () {
  return new Promise((resolve, reject) => {
    con.connect(function (err) {
      if (err) {
        console.log('连接数据库出错:', err);
        reject(err); // 抛出错误
      } else {
        con.query("SELECT * FROM Users", function (err, result, fields) {
          if (err) {
            console.log('查询出错:', err);
            reject(err);
          } else {
            resolve(result); // 返回查询结果
          }
        });
      }
    });
  });
}

然后在控制器里用async/await等待Promise完成:

exports.get_all_users = async function (req, res) {
  try {
    // 等待查询结果返回
    const arr = await UserModel.getAllUsers();
    res.send(arr);
  } catch (err) {
    // 捕获错误并处理
    res.status(500).send('数据库查询失败');
    console.error(err);
  }
}

额外优化建议

你不需要每次查询都调用con.connect()——频繁建立/断开连接会影响性能。建议使用MySQL连接池,或者在应用启动时建立一次连接并复用它,这样能大幅提升数据库操作的效率。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 07:36:45