NodeJS/Express:如何将MySQL查询结果赋值给变量?
问题解决方案
你的代码核心问题是同时混用了回调函数和async/await,导致数据库查询的回调提前调用result返回结果,函数直接终止,后续的GCS代码根本没机会执行。另外直接拼接userId到SQL语句里还存在SQL注入风险,必须修复。
修改后的代码(适配支持Promise的SQL库,如mysql2/promise)
const File = function (file) { this.userId = file.userId; this.fileName = file.fileName; }; File.getAvi = async (userId, result) => { try { // 用await获取查询结果,放弃回调模式 const [rows] = await sql.query(`SELECT fileName FROM avatars WHERE userId = ?`, [userId]); // 检查是否查询到数据 if (rows.length === 0) { return result(new Error("未找到该用户的头像文件"), null); } const fileName = rows[0].fileName; // 调用GCS获取文件元数据 const [metadata] = await bucket.file(fileName).getMetadata(); // 返回最终的元数据结果 result(null, metadata); } catch (err) { console.log("处理过程出错: ", err); result(err, null); } };
关键修改点说明
- 放弃回调,统一用async/await:数据库查询改用Promise形式,确保代码按顺序执行,不会提前触发
result返回。 - 参数化查询:用
?占位符替代字符串拼接${userId},彻底避免SQL注入风险。 - 统一错误捕获:用
try/catch包裹所有异步操作,不管是数据库查询还是GCS调用出错,都能统一处理并返回错误信息。 - 空结果检查:判断查询返回的行数,避免后续访问
rows[0]时出现undefined错误。
适配不支持Promise的旧版SQL库(如mysql)
如果你的SQL库不原生支持Promise,需要手动封装一个Promise版的查询函数:
// 封装Promise版的查询工具函数 const queryPromise = (sqlQuery, params) => { return new Promise((resolve, reject) => { sql.query(sqlQuery, params, (err, res) => { if (err) reject(err); else resolve(res); }); }); }; const File = function (file) { this.userId = file.userId; this.fileName = file.fileName; }; File.getAvi = async (userId, result) => { try { const rows = await queryPromise(`SELECT fileName FROM avatars WHERE userId = ?`, [userId]); if (rows.length === 0) { return result(new Error("未找到该用户的头像文件"), null); } const fileName = rows[0].fileName; const [metadata] = await bucket.file(fileName).getMetadata(); result(null, metadata); } catch (err) { console.log("处理过程出错: ", err); result(err, null); } };
内容的提问来源于stack exchange,提问作者alphatango165
相关产品推荐
相关产品推荐

