async函数结合SQL查询时出现Cannot read property 'user' of undefined报错
问题原因
你当前代码的核心问题是同时混用了回调异步语法和async/await的Promise异步语法,二者逻辑冲突导致执行顺序不符合预期:
- 主流Node.js数据库驱动的
query方法传入回调参数时,返回值不是Promise对象,你写的await不会生效,代码会直接向下执行,最终fetch函数此时返回的是undefined - 你在外部拿到这个
undefined后读取user属性,就会触发Cannot read property 'user' of undefined报错 - 回调函数会在数据库请求返回后异步执行,此时已经报错完成,所以控制台会在报错后打印出
result[0].user的内容
修复方案
方案1:使用驱动自带的Promise API(推荐)
现在绝大多数数据库驱动(如mysql2、pg等)都原生支持Promise调用,不需要传入回调,直接await即可拿到结果:
fetch: async (id) => { if (id!=='something') { const connection = await db.getConnection(); // 使用参数化查询避免SQL注入,禁止直接拼接用户输入到SQL语句中 const [result] = await connection.query("SELECT user FROM `table` WHERE id = ?", [id]); connection.release(); // 连接使用完成后必须释放,避免连接泄漏 console.log(result[0].user); return result[0].user; } throw new Error('Failed fetching installation'); }
方案2:手动封装回调为Promise
如果你的数据库驱动不支持Promise调用,可以手动将回调逻辑封装为Promise:
fetch: async (id) => { if (id!=='something') { const connection = await db.getConnection(); return new Promise((resolve, reject) => { connection.query("SELECT user FROM `table` WHERE id = ?", [id], function (err, result) { connection.release(); if (err) return reject(err); console.log(result[0].user); resolve(result[0].user); }); }) } throw new Error('Failed fetching installation'); }
注意事项
- 调用
fetch方法时必须配合await或者.then()获取返回结果,直接调用拿到的是Promise对象,无法直接读取user属性 - 原代码中直接拼接
id到SQL语句的写法存在严重的SQL注入风险,必须使用参数化查询的方式传入参数,由驱动自动做转义处理
内容的提问来源于stack exchange,提问作者binoculars
相关产品推荐
相关产品推荐

