You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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,但问题依旧。


可能的原因及解决步骤

  1. 确认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);
              });
          });
      }
      
  2. 检查getUser的返回结果是否符合预期
    在let a = await this.getUser(header.userid)后添加日志:console.log('getUser查询结果:', a),确认:

    • 结果是否为非空数组;
    • a[0]是否存在,且a[0].role有有效值。
      如果结果为空数组,说明数据库中没有对应用户的记录,需检查传入的userid是否正确。
  3. 验证数据库连接的注入是否正确
    确保DB_CONNECTION(或修改后的ASYNC_CONNECTION)在模块中正确声明为provider,且Service中通过@Inject(DB_CONNECTION)成功注入了conn对象。如果conn是undefined,query调用会抛出异常,可能未被捕获导致流程异常。

  4. 修复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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 16:03:10