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

尝试将SQL查询封装为Promise失败,求技术解决方法

SQL查询Promise封装的问题修复方案

嘿,我看了你的Promise封装代码,发现几个关键问题导致它没法正常运行,咱们一个个来解决:

问题分析

  • 错误处理逻辑错误:当connection.query执行出错时,你用resolve([])返回空数组,这会让调用方误以为查询成功了,根本捕获不到错误。Promise的设计就是用reject来传递错误,resolve只用于成功场景。
  • 连接释放存在泄漏风险:虽然你写了connection.release(),但如果connection.query的回调因为某些异常没执行到,连接就会一直占着,时间长了连接池会被耗尽。
  • SQL格式化的优化点:你在获取连接前就用mysql.format处理SQL,其实用当前连接实例的format方法会更适配连接配置,比如字符集、转义规则等,更安全。

修正后的代码

query: (sql, args) => {
  return new Promise((resolve, reject) => {
    pool.getConnection((err, connection) => {
      if (err) {
        console.error('获取数据库连接失败:', err);
        return reject(new Error(err.code));
      }

      // 使用当前连接的format方法处理SQL参数
      const formattedSql = args ? connection.format(sql, args) : sql;

      connection.query(formattedSql, (err, results) => {
        // 无论查询成功或失败,都确保连接被放回池子里
        connection.release();

        if (err) {
          console.error('SQL查询执行失败:', err);
          return reject(err); // 正确抛出错误
        }

        resolve(results);
      });
    });
  });
}

使用示例(async/await方式)

这样调用的话,错误处理会更清晰:

async function getUserById(userId) {
  try {
    const user = await query('SELECT * FROM users WHERE id = ?', [userId]);
    return user[0]; // 假设返回单条数据
  } catch (err) {
    console.error('获取用户信息失败:', err);
    throw err; // 可以向上抛出错误,让上层处理
  }
}

额外建议

  • 尽量避免在获取连接前格式化SQL,因为不同连接可能有不同的转义规则,用connection.format更稳妥。
  • 可以给reject传递完整的错误对象,而不只是err.code,这样调试时能看到更详细的错误信息。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 08:38:35