NestJS+MySQL未用TypeORM,async/await未等待SQL执行问题求助
问题排查:NestJS中async/await未按预期等待SQL查询完成
我在使用NestJS和MySQL,未采用TypeORM。需要执行多条SQL语句,第二条需使用第一条的执行结果,但即便用了async/await,程序也没等getUser()执行完成就运行getGetMenuParents(),导致传入该方法的role参数为undefined,请求帮忙排查。
业务代码
async findMenu(header) { if (!header.userid) throw new HttpException('Userid not supplied', HttpStatus.FORBIDDEN); let a = await this.getUser(header.userid) let b = await this.getGetMenuParents(a[0].role) return b[0]; } async getUser(userid:string) { const sql =`select role from gb_users where userid = '${userid}'` const result = await this.conn.query(sql); return result; } async getGetMenuParents(role:string) { const sql =`select * from gb_roles where role = '${role}'`; const result = await this.conn.query(sql); return result; }
数据库连接配置
const dbProvider = { inject: [ConfigService], provide: DB_CONNECTION, useFactory: async (configService: ConfigService) => { return await mysql.createConnection({ user: configService.get<string>('database.username'), host: configService.get<string>('database.host'), database: configService.get<string>('database.database'), password: configService.get<string>('database.password'), port: parseInt( configService.get<string>('database.port'), 3306), }) }, };
我试过把DB_CONNECTION改成ASYNC_CONNECTION,但问题依旧。
可能的原因及解决步骤
确认MySQL库的query方法是否支持Promise
如果你用的是原生mysql包,它的query方法默认是回调式,并非Promise。这种情况下await不会生效,程序会直接往下执行。解决办法:- 换成
mysql2/promise包,它的query方法天然返回Promise,能正常被await等待; - 若坚持用原生
mysql,手动将query包装成Promise:async getUser(userid:string) { return new Promise((resolve, reject) => { const sql = 'select role from gb_users where userid = ?'; this.conn.query(sql, [userid], (err, result) => { if (err) reject(err); else resolve(result); }); }); }
- 换成
检查getUser的返回结果是否符合预期
在let a = await this.getUser(header.userid)后添加日志:console.log('getUser查询结果:', a),确认:- 结果是否为非空数组;
a[0]是否存在,且a[0].role有有效值。
如果结果为空数组,说明数据库中没有对应用户的记录,需检查传入的userid是否正确。
验证数据库连接的注入是否正确
确保DB_CONNECTION(或修改后的ASYNC_CONNECTION)在模块中正确声明为provider,且Service中通过@Inject(DB_CONNECTION)成功注入了conn对象。如果conn是undefined,query调用会抛出异常,可能未被捕获导致流程异常。修复SQL注入漏洞
当前用字符串拼接SQL的方式存在严重安全问题,无论问题是否解决,都要改成参数化查询:// getUser改为参数化查询 async getUser(userid:string) { const sql = 'select role from gb_users where userid = ?'; const result = await this.conn.query(sql, [userid]); return result; } // getGetMenuParents同理 async getGetMenuParents(role:string) { const sql = 'select * from gb_roles where role = ?'; const result = await this.conn.query(sql, [role]); return result; }
内容的提问来源于stack exchange,提问作者Suraj PACC
相关产品推荐
相关产品推荐

