Node.js问题:变量值传递至控制器后无法正常返回的排查
Node.js异步回调导致API无法返回数据库查询结果的问题解决
问题根源
- 异步执行顺序错误:
GloParameter.findGlo是异步数据库操作,控制器中直接将其返回值赋值给xx1时,回调函数还未执行,此时xx1为undefined,代码会直接执行res.send,导致返回空数据。 - 参数传递不匹配:
findGlo方法需要接收gloFunction、gloCode、gloValue三个查询参数加回调函数,但控制器调用时只传了一个数组和回调,导致SQL查询参数错位,无法正确查询数据。 - 回调数据处理错误:
findGlo的回调中data已经是res[0](单个对象),代码中却尝试取data[0].glo_info1,会触发Cannot read properties of undefined错误。 - SQL语句引用错误:Model中使用的
findGloParameterFCVActiveQuery变量,与db模块导出的findGloParameterFCVActive名称不匹配,导致查询语句无效。
修复方案1:修正回调写法
修复后的Controller代码
exports.serviceX = (req, res) => { // 正确传递三个查询参数,对应SQL的三个?占位符 GloParameter.findGlo('withdraw_money_time', 'withdraw_money_time', 'start', (err, data) => { if (err) { return res.status(err.kind === 'not_found' ? 404 : 500).send({ status: 'error', message: err.message || '数据查询失败' }); } // data是单个对象,直接取目标字段 res.status(200).send({ status: 'success', data: data.glo_info1 }); }); }
修复后的Model代码
const { findGloParameterFCVActive } = require('./db'); // 确保db路径正确 class GloParameter { static findGlo(gloFunction, gloCode, gloValue, cb) { // 使用数组传递查询参数,避免顺序错误 db.query(findGloParameterFCVActive, [gloFunction, gloCode, gloValue], (err, res) => { if (err) { logger.error(err.message); cb(err, null); return; } if (res.length) { cb(null, res[0]); return; } cb({ kind: "not_found", message: "未找到匹配数据" }, null); }) } } module.exports = GloParameter;
修复方案2:改用Promise+async/await(更现代的写法)
回调嵌套易出错,推荐将Model改为Promise风格,代码可读性更强。
改造后的Model代码
const { findGloParameterFCVActive } = require('./db'); class GloParameter { static findGlo(gloFunction, gloCode, gloValue) { return new Promise((resolve, reject) => { db.query(findGloParameterFCVActive, [gloFunction, gloCode, gloValue], (err, res) => { if (err) { logger.error(err.message); return reject(err); } res.length ? resolve(res[0]) : reject({ kind: "not_found", message: "未找到匹配数据" }); }); }); } } module.exports = GloParameter;
对应Controller代码
exports.serviceX = async (req, res) => { try { const data = await GloParameter.findGlo('withdraw_money_time', 'withdraw_money_time', 'start'); res.status(200).send({ status: 'success', data: data.glo_info1 }); } catch (err) { res.status(err.kind === 'not_found' ? 404 : 500).send({ status: 'error', message: err.message || '数据查询失败' }); } }
内容的提问来源于stack exchange,提问作者momoman
相关产品推荐
相关产品推荐

