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

mysql2 Promise客户端报错:Callback function不可用 求解决方法

问题:使用MySQL2 Promise客户端时,save方法报错「Callback function is not available with promise clients」

原始代码与错误

Post类的save方法

class Post{
  title = "";
  body = "";
  constructor(title: string, body: string) {
    this.title = title;
    this.body = body;
  }

   save(): Promise<IPost> {
    const d = new Date();
    const yyyy = d.getFullYear();
    const mm = d.getMonth() + 1;
    const dd = d.getDate();

    const createdAtDate = `${yyyy}-${mm}-${dd}`;

    const sql = `
    INSERT INTO posts(
      title,
      body,
      created_at
    )
    VALUES(
      '${this.title}',
      '${this.body}',
      '${createdAtDate}'
    )
    `;

    return new Promise<IPost>((resolve, reject) => {
      db.execute<OkPacket>(sql, (err: Error, res: Response) => {
        if (err) {
          reject(err);
          console.log(err);
        }
        else resolve(res.json())
      });
    });
  }
}

数据库配置db.ts

import dotenv from "dotenv";
dotenv.config();
import mysql from "mysql2";

const pool = mysql.createPool({
  host: process.env.DB_HOST,
  user: process.env.DB_USER,
  database: process.env.DB_NAME,
  password: process.env.DB_PASSWORD,
});

export default pool.promise();

运行错误

Error: Callback function is not available with promise clients.

解决方案

核心问题

你导出的是pool.promise()生成的Promise版本客户端,它的execute方法本身就返回Promise,不支持传入回调函数,同时原始代码存在SQL注入风险,需要同步修复。

修改后的save方法代码

// 先定义IPost类型(根据你的数据库表结构调整)
interface IPost {
  id: number;
  title: string;
  body: string;
  created_at: string;
}

// 引入mysql2的类型定义
import { OkPacket } from "mysql2";

class Post{
  title = "";
  body = "";
  constructor(title: string, body: string) {
    this.title = title;
    this.body = body;
  }

  async save(): Promise<IPost> {
    // 使用参数化查询,彻底避免SQL注入
    const sql = `
      INSERT INTO posts(title, body, created_at)
      VALUES(?, ?, CURDATE())
    `;

    // 直接使用Promise版本的execute,无需手动包裹Promise
    const [result] = await db.execute<OkPacket>(sql, [this.title, this.body]);
    
    // 组装并返回符合IPost类型的新增记录信息
    return {
      id: result.insertId,
      title: this.title,
      body: this.body,
      created_at: new Date().toISOString().split('T')[0]
    };
  }
}

关键修改点

  • 移除手动创建的new Promise,改用async/await语法直接调用db.execute返回的Promise
  • 将SQL中的字符串拼接替换为?占位符,参数通过数组传入execute,杜绝SQL注入风险
  • 使用MySQL内置的CURDATE()函数生成当前日期,简化前端日期拼接逻辑
  • 利用OkPacket类型获取新增记录的insertId,确保返回值符合IPost类型定义

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 10:45:19