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
相关产品推荐
相关产品推荐

