Node.js模块中回调函数无法正确返回数据库查询结果问题
搞定你的异步回调问题!
嘿,我一眼就看出问题出在哪了——这完全是异步回调的执行顺序在搞鬼!
你写的userById函数里,db.executeSql是个异步操作:它会立刻返回,然后后台去执行数据库查询,等查询完成了才会调用你传入的回调函数。但你在回调里写的return data.recordset,这个返回值根本不会传递给userById的调用者——因为外层的userById早就在异步查询开始前就执行完了,它根本等不到回调里的结果。
下面给你几种实用的解决方案,挑你顺手的用:
方案1:给模块加个回调参数
最直接的方式是让你的userById也接受一个回调函数,把查询结果通过这个回调传递出去(遵循Node.js错误优先的回调惯例会更规范):
exports.userById = (id, callback) => { db.executeSql(`SELECT * FROM Users WHERE UserId = ${id}`, function(data, err) { if (err) { // 错误优先:第一个参数传错误,第二个传null callback(err, null); } else { // 成功时第一个参数传null,第二个传结果 callback(null, data.recordset); } }); }
调用的时候这么用:
const userModule = require('./你的模块路径'); userModule.userById(123, (err, user) => { if (err) { console.error('拿用户数据失败:', err); return; } console.log('查到的用户:', user); });
方案2:用Promise封装(更优雅)
如果不想写嵌套回调,用Promise封装后,还能配合async/await让代码像同步一样好读:
exports.userById = (id) => { return new Promise((resolve, reject) => { db.executeSql(`SELECT * FROM Users WHERE UserId = ${id}`, function(data, err) { if (err) { reject(err); // 查询失败就抛出错误 } else { resolve(data.recordset); // 查询成功就返回结果 } }); }); }
调用方式有两种:
// 方式1:用.then()链式调用 const userModule = require('./你的模块路径'); userModule.userById(123) .then(user => console.log('用户信息:', user)) .catch(err => console.error('出错了:', err)); // 方式2:用async/await(必须在async函数里用) async function fetchUser() { try { const user = await userModule.userById(123); console.log('用户信息:', user); } catch (err) { console.error('获取用户失败:', err); } } fetchUser();
重要提醒:小心SQL注入!
哦对了,你现在直接把id拼进SQL语句里,这有严重的SQL注入风险!比如有人传个123; DROP TABLE Users;当id,你的数据库就凉了。赶紧改成参数化查询,比如(具体写法看你用的数据库库):
// 用占位符?代替直接拼接,把参数放在数组里传递 db.executeSql(`SELECT * FROM Users WHERE UserId = ?`, [id], function(data, err) { // 后续逻辑不变 });
内容的提问来源于stack exchange,提问作者J.Kirk.
相关产品推荐
相关产品推荐

