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

NodeJS中如何用Promise处理MySQL连接,解决连接关闭状态错误

问题描述

我正在用NodeJS和MySQL服务器开发学校项目,试图创建包装函数处理连接并通过回调执行其他函数,但无法让处理函数中前两个函数执行,也无法等待回调完全执行后再关闭连接,目前遇到错误:Error: Can't add new command when connection is in closed state。

相关代码如下:

let mysql = require('mysql2');
let con = mysql.createConnection({
    host: '',
    user: '',
    password: ''
})

function connectionHandler(_callback) {
    con.connect(function (err) {
        if (err)
            throw err;
        console.log('Connected!');
    });

    con.query('USE test', function (err) {
        if (err)
            throw err;
    });

    _callback;

    con.end(function (err) {
        if (err)
            throw err;
    });
}

function addOrder() {
    con.query('INSERT INTO orders', function (err) {
        if (err)
            throw err;
    });
}

connectionHandler(addOrder());

请问如何使用Promise实现正确的流程?


基于Promise的修正方案

问题根源

原代码的核心问题是异步操作没有按顺序等待:

  • con.connect、con.query都是异步操作,代码直接跳过它们执行con.end,导致连接提前关闭
  • 调用connectionHandler(addOrder())时直接执行了addOrder,没有把函数作为回调传递
  • 没有处理异步操作的完成状态,无法保证回调执行完毕再关闭连接

实现步骤

  1. 使用mysql2原生Promise API:无需手动封装,直接用mysql2/promise简化异步流程
  2. 按顺序执行异步逻辑:建立连接 → 执行业务操作 → 关闭连接,每一步都等待完成
  3. 用try/catch/finally保证资源回收:无论操作成功失败,都确保连接关闭
  4. 让业务回调返回Promise:保证处理函数能等待业务操作完成

完整修正代码

// 引入mysql2的Promise版本
const mysql = require('mysql2/promise');

// 封装连接处理的异步函数
async function connectionHandler(callback) {
    let connection;
    try {
        // 1. 创建并建立数据库连接,直接指定目标数据库
        connection = await mysql.createConnection({
            host: '',
            user: '',
            password: '',
            database: 'test'
        });
        console.log('Connected!');

        // 2. 执行业务回调,等待其完成
        await callback(connection);

    } catch (err) {
        console.error('操作出错:', err);
        throw err; // 抛出错误供调用方处理
    } finally {
        // 3. 无论成功失败,确保连接关闭
        if (connection) {
            await connection.end();
            console.log('Connection closed!');
        }
    }
}

// 业务函数:接收连接对象,返回Promise
async function addOrder(connection) {
    // 执行插入操作,await等待操作完成
    // 注意:INSERT语句需要指定字段或值,示例中补充占位符
    await connection.query('INSERT INTO orders (order_date) VALUES (?)', ['2024-05-20']);
    console.log('Order added successfully!');
}

// 启动执行流程
(async () => {
    await connectionHandler(addOrder); // 传递函数引用,而非执行结果
})();

关键说明

  • 使用mysql2/promise替代回调版API,用await替代嵌套回调,代码更简洁易读
  • 在连接配置中直接指定database,省去额外的USE test查询步骤
  • 业务函数接收连接对象,避免全局连接的并发问题
  • 调用connectionHandler时传递函数引用addOrder,让处理函数内部控制执行时机
  • finally块确保连接一定会关闭,避免数据库连接资源泄漏

内容的提问来源于stack exchange,提问作者Mr. Goose

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 07:05:51