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

从Promise-Mysql迁移到Mysql2,如何修改updateOrder中的Promise.resolve()?

问题

我正在把原本用Promise-Mysql的代码重构为Mysql2,整体进展顺利,但Promise相关的代码处理遇到了问题(我对Promise不太熟)。

原Promise-Mysql代码:

Promise.all([
        db.query("UPDATE gantt_tasks SET text = ?, start_date = ?, duration = ?, progress = ?, parent = ? WHERE id = ?",
            [task.text, task.start_date, task.duration, task.progress, task.parent, sid]),
        updateOrder(sid, target)
    ])
        .then(function (result) {
            sendResponse(res, "updated");
        })
        .catch(function (error) {
            sendResponse(res, "error", null, error);
        });

现在改成了Mysql2的回调写法:

con1.execute("UPDATE gantt_tasks SET text = ?, start_date = ?, duration = ?, progress = ?, parent = ? WHERE id = ?",
        [task.text, task.start_date, task.duration, task.progress, task.parent, sid], function (err, result, fields) {
            if (err) { sendResponse(res, "error", null, error); }
            updateOrder(sid, target);
            sendResponse(res, "updated");
        });

updateOrder函数目前还是Promise写法:

function updateOrder(taskId, target) {
    var nextTask = false;
    var targetOrder;

    target = target || "";

    if (target.startsWith("next:")) {
        target = target.substr("next:".length);
        nextTask = true;
    }

    return db.query("SELECT * FROM gantt_tasks WHERE id = ?", [target])
        .then(function (result) {
            if (!result[0])
                return Promise.resolve();

            targetOrder = result[0].sortorder;
            if (nextTask)
                targetOrder++;

            return db.query("UPDATE gantt_tasks SET sortorder = sortorder + 1 WHERE sortorder >= ?",[targetOrder])
                .then(function (result) {return db.query("UPDATE gantt_tasks SET sortorder = ? WHERE id = ?",[targetOrder, taskId]); });
        });
}

我的疑问是:现在代码改用回调了,updateOrder里的return Promise.resolve();该怎么修改?


解决方案

方案1:保留Promise逻辑(推荐,贴合原代码并行执行逻辑)

Mysql2本身支持Promise API,不需要完全放弃Promise,这样能保留原代码中Promise.all并行执行两个操作的优点,避免回调嵌套。

  1. 先把Mysql2连接转换成Promise版本:
const con1Promise = con1.promise(); // 将回调式连接转为Promise式
  1. 重构主代码,和原结构几乎一致:
Promise.all([
    con1Promise.execute("UPDATE gantt_tasks SET text = ?, start_date = ?, duration = ?, progress = ?, parent = ? WHERE id = ?",
        [task.text, task.start_date, task.duration, task.progress, task.parent, sid]),
    updateOrder(sid, target)
])
.then(function () {
    sendResponse(res, "updated");
})
.catch(function (error) {
    sendResponse(res, "error", null, error);
});
  1. 修改updateOrder里的数据库操作,同时简化Promise.resolve():
function updateOrder(taskId, target) {
    var nextTask = false;
    var targetOrder;

    target = target || "";

    if (target.startsWith("next:")) {
        target = target.substr("next:".length);
        nextTask = true;
    }

    return con1Promise.execute("SELECT * FROM gantt_tasks WHERE id = ?", [target])
        .then(function ([result]) { // Mysql2的execute返回[结果集, 字段信息],解构取第一个
            if (!result[0])
                return; // 这里直接return即可,效果和return Promise.resolve()完全一致

            targetOrder = result[0].sortorder;
            if (nextTask)
                targetOrder++;

            return con1Promise.execute("UPDATE gantt_tasks SET sortorder = sortorder + 1 WHERE sortorder >= ?",[targetOrder])
                .then(function () {
                    return con1Promise.execute("UPDATE gantt_tasks SET sortorder = ? WHERE id = ?",[targetOrder, taskId]);
                });
        });
}

方案2:完全改成回调写法

如果一定要用纯回调,需要给updateOrder添加回调参数,把Promise链式调用改成嵌套回调:

  1. 修改updateOrder函数:
function updateOrder(taskId, target, callback) {
    var nextTask = false;
    var targetOrder;

    target = target || "";
    callback = callback || function(){}; // 默认空回调避免报错

    if (target.startsWith("next:")) {
        target = target.substr("next:".length);
        nextTask = true;
    }

    con1.execute("SELECT * FROM gantt_tasks WHERE id = ?", [target], function(err, result) {
        if (err) return callback(err);
        if (!result[0]) return callback(null); // 替代原return Promise.resolve(),调用回调传递空错误参数
        
        targetOrder = result[0].sortorder;
        if (nextTask)
            targetOrder++;

        con1.execute("UPDATE gantt_tasks SET sortorder = sortorder + 1 WHERE sortorder >= ?",[targetOrder], function(err) {
            if (err) return callback(err);
            con1.execute("UPDATE gantt_tasks SET sortorder = ? WHERE id = ?",[targetOrder, taskId], callback);
        });
    });
}
  1. 修改主调用代码,确保两个异步操作都完成后再响应:
let completedCount = 0;
let errorOccurred = false;

function handleTaskComplete(err) {
    if (err && !errorOccurred) {
        errorOccurred = true;
        sendResponse(res, "error", null, err);
        return;
    }
    completedCount++;
    if (completedCount === 2 && !errorOccurred) {
        sendResponse(res, "updated");
    }
}

// 执行第一个更新
con1.execute("UPDATE gantt_tasks SET text = ?, start_date = ?, duration = ?, progress = ?, parent = ? WHERE id = ?",
    [task.text, task.start_date, task.duration, task.progress, task.parent, sid], function(err) {
        handleTaskComplete(err);
    });

// 执行updateOrder
updateOrder(sid, target, function(err) {
    handleTaskComplete(err);
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 09:35:39