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

Node.js自定义JS函数返回MySQL数据问题及异步改造报错

问题分析与解决方案

初始代码返回undefined的原因

JavaScript中数据库查询是异步操作,你的初始代码里getAllUrls函数在conn.query的回调执行前就已经执行完conn.end()并结束了函数,此时result还没被赋值,函数没有返回有效数据,所以调用时得到undefined。同时conn.end()提前执行还会导致查询未完成就断开连接。

改造后连接关闭错误的原因

在egallery.js模块加载阶段,你先调用conn.connect(),然后定义函数,紧接着直接执行conn.end()——这会导致数据库连接在模块加载完成后就被关闭。后续请求触发getAllUrls执行conn.query时,连接处于关闭状态,因此抛出Can't add new command when connection is in closed state错误。


推荐解决方案:使用数据库连接池(性能最优)

连接池可以复用数据库连接,避免频繁创建/销毁连接的性能损耗,是生产环境的首选方案。

1. 修改conn.js,创建连接池

const mysql = require('mysql2/promise');
// 替换为你的数据库配置
const pool = mysql.createPool({
  host: '你的数据库主机地址',
  user: '数据库用户名',
  password: '数据库密码',
  database: '目标数据库名',
  connectionLimit: 10, // 连接池最大连接数
  waitForConnections: true
});

module.exports = pool;

2. 修改egallery.js,基于连接池封装查询函数

const pool = require('./conn.js');

async function getAllUrls() {
  try {
    // 使用连接池执行查询,直接返回结果
    const [rows] = await pool.query('SELECT * FROM ray_url');
    return rows;
  } catch (err) {
    // 抛出错误,让上层调用处理
    throw err;
  }
}

module.exports = { getAllUrls };

3. 保留app.js的async/await调用,增加错误处理

let app = require('express')();
var egallery = require('./models/egallery.js');

app.set('view engine', 'ejs');
app.get('/e', async (req, res) => {
  try {
    const rows = await egallery.getAllUrls();
    console.log(rows);
    res.render('pages/index', { rows: rows });
  } catch (err) {
    // 捕获错误并返回友好提示
    console.error(err);
    res.status(500).send('服务器内部错误');
  }
})

app.get('/e/about', function(req, res) {
  res.render('pages/about');
});

app.listen(3000, '0.0.0.0');

备选方案:每次查询临时创建连接(不推荐)

如果不想用连接池,可以在每次查询时创建连接,查询完成后再关闭:

// egallery.js修改为
const conn = require('./conn.js');

function getAllUrls() {
  return new Promise((resolve, reject) => {
    conn.connect((connectErr) => {
      if (connectErr) return reject(connectErr);
      
      conn.query('SELECT * FROM ray_url', (queryErr, result) => {
        // 查询完成后关闭连接
        conn.end();
        queryErr ? reject(queryErr) : resolve(result);
      });
    });
  });
}

module.exports = { getAllUrls };

app.js的调用逻辑不变,同样需要保留错误处理。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 05:25:51