NodeJS中MySQL查询结果数组返回到调用函数时为undefined
NodeJS异步函数返回undefined问题的解决方案
问题原因
你遇到的问题核心是异步操作的返回值处理错误:
dbc.query是异步执行的数据库查询,它的回调函数会在查询完成后才触发- 你在回调里
return rows,但这个return属于回调函数本身,不是外层的quesAnswers函数的返回值 quesAnswers函数在调用dbc.query后会直接执行完毕,没有返回任何有效数据(仅在未登录时返回null),所以调用时得到undefined,自然无法读取length属性
修复方案
方案1:使用回调函数传递结果
修改quesAnswers,新增一个回调参数来传递查询结果:
模块内的quesAnswers函数:
quesAnswers: (request, response, callback) => { console.log('/quesAnswers ' + request.params.quesID); // 用const声明变量,避免全局污染 const quesID = request.params.quesID; if (request.session.loggedin) { const dbc = require('../mods/db.js'); dbc.query(` SELECT sa.* FROM sa WHERE sa.id = ? ORDER BY cdate DESC `, // 直接传参数数组,不需要赋值给values变量 [quesID], function (err, rows) { if (err) { response.render('pages/err', { err: err }); callback(err, null); return; } else { console.log('arows: ', rows.length); // 通过回调传递结果 callback(null, rows); } }) } else { response.render('pages/please_login'); callback(null, null); } }
调用代码修改:
module.exports.quesAnswers(request, response, (err, arows) => { if (err) { // 额外处理错误,比如返回错误页面 return; } // 用可选链避免arrows为null/undefined时报错 console.log('arows.length: ', arows?.length); response.render('pages/test_ques_view', { qdata: rows, adata: arows }); });
方案2:用Promise封装 + async/await(更现代的写法)
把quesAnswers改成返回Promise的函数,配合async/await来处理异步结果:
模块内的quesAnswers函数:
quesAnswers: (request, response) => { return new Promise((resolve, reject) => { console.log('/quesAnswers ' + request.params.quesID); const quesID = request.params.quesID; if (request.session.loggedin) { const dbc = require('../mods/db.js'); dbc.query(` SELECT sa.* FROM sa WHERE sa.id = ? ORDER BY cdate DESC `, [quesID], function (err, rows) { if (err) { response.render('pages/err', { err: err }); reject(err); return; } else { console.log('arows: ', rows.length); resolve(rows); } }) } else { response.render('pages/please_login'); resolve(null); } }); }
调用代码(注意调用代码必须在async函数内):
// 确保此函数被标记为async async function renderQuesView(request, response) { try { const arows = await module.exports.quesAnswers(request, response); console.log('arows.length: ', arows?.length); response.render('pages/test_ques_view', { qdata: rows, adata: arows }); } catch (err) { // 捕获并处理错误 console.error(err); } } // 调用这个async函数 renderQuesView(request, response);
额外注意事项
- 避免未声明的全局变量:原代码中
quesID没有用const/let声明,会变成全局变量,容易引发逻辑错误,一定要加上声明 - 可选链运算符
?.:在访问arows.length时使用arows?.length,可以避免arows为null或undefined时抛出错误 - 数据库连接模块:
require('../mods/db.js')最好放在模块顶部,而不是函数内部重复加载,提升性能
内容的提问来源于stack exchange,提问作者Pro West
相关产品推荐
相关产品推荐

