从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并行执行两个操作的优点,避免回调嵌套。
- 先把Mysql2连接转换成Promise版本:
const con1Promise = con1.promise(); // 将回调式连接转为Promise式
- 重构主代码,和原结构几乎一致:
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); });
- 修改
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链式调用改成嵌套回调:
- 修改
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); }); }); }
- 修改主调用代码,确保两个异步操作都完成后再响应:
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
相关产品推荐
相关产品推荐

