如何在Node.js中用Promise重构CPS风格的MySQL操作代码?
没问题!我帮你把这段CPS风格的Node.js代码重构为基于Promise和async/await的版本——这会让代码可读性、维护性提升不少,还能避免回调嵌套的问题。先看一下重构后的代码,再一步步解释改动点:
重构后的代码(基于Promise + async/await)
首先推荐使用mysql2/promise(原生支持Promise的MySQL客户端),替代原有的回调式mysql模块,这样不用手动封装Promise:
const mysql = require('mysql2/promise'); exports.execute = async function (input) { let conn; try { // 原有的数据库配置 const config = {...}; // 建立数据库连接(Promise化,await直接获取连接) conn = await mysql.createConnection(config); // 1. 执行校验查询(对应原CPS的第一个步骤) let validateRes = null; if (input.test?.query) { // 用可选链简化null判断 validateRes = await conn.query(input.test.query); } // 2. 校验结果或执行主查询(对应原CPS的第二个步骤) let queryRes = null; const isValid = (!validateRes && !input.test) || (input.test?.validate?.(validateRes) === true); if (isValid) { if (input.query) { queryRes = await conn.query(input.query); } } else { const errorMsg = { level: "error", message: input.test?.error || "校验未通过" }; console.log(errorMsg); throw new Error(JSON.stringify(errorMsg)); // 抛出错误,统一进入catch处理 } // 3. 执行结果处理动作(对应原CPS的第三个步骤) console.log("[RDS-BASE] Executing input action"); const actionRes = input.action(queryRes); // 4. 校验处理结果并返回(对应原CPS的第四个步骤) console.log("[RDS-BASE] Executing response"); if (!actionRes) { const errorMsg = { level: "error", message: "Missing result" }; console.log(errorMsg); throw new Error(JSON.stringify(errorMsg)); } // 返回最终结果 return actionRes; } catch (err) { // 统一处理所有错误,替代原代码中多次重复的callback错误调用 const errorMessage = typeof err === 'string' ? err : JSON.stringify({ level: "error", message: err.message || err }); console.error(errorMessage); throw new Error(errorMessage); // 抛出错误让调用者处理 } finally { // 无论成功/失败,确保关闭数据库连接,避免资源泄漏 if (conn) { await conn.end(); console.log("数据库连接已关闭"); } } };
关键改动说明
Promise化数据库操作:
用mysql2/promise替代原生mysql,所有异步操作(连接、查询)都返回Promise,直接用await等待结果,告别回调函数。用async/await替代CPS串行执行:
原cps.seq的串行逻辑,现在用线性的await语句实现,代码逻辑一目了然,不需要嵌套的handle回调。统一错误处理:
所有错误(连接失败、校验失败、结果缺失等)都通过throw抛出,最终在catch块统一处理,避免原代码中重复的错误消息构造和callback调用。确保资源释放:
用finally块保证数据库连接一定会被关闭,不管流程是成功还是报错,避免资源泄漏问题。简化空值判断:
使用ES6+的可选链操作符?.替代原有的null !== xxx判断,代码更简洁安全。
调用示例
重构后的方法可以通过Promise链式调用,或者在async函数中用await调用:
// 方式1:Promise链式调用 execute(yourInputData) .then(result => { console.log("执行成功:", result); // 这里可以处理返回结果 }) .catch(err => { console.error("执行失败:", err.message); // 处理错误 }); // 方式2:在async函数中调用 async function runTask() { try { const result = await execute(yourInputData); console.log("执行成功:", result); } catch (err) { console.error("执行失败:", err.message); } } runTask();
内容的提问来源于stack exchange,提问作者Rajarshi Das
相关产品推荐
相关产品推荐

