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

如何正确使用AsyncIterator?解决for await...of报错问题

解决AsyncIterator无法使用for await...of的问题

问题核心

for await...of语法要求迭代对象必须实现**AsyncIterable接口**——也就是对象要有[Symbol.asyncIterator]()方法,返回一个AsyncIterator。你当前的接口定义tables()返回的是AsyncIterator<Table>,虽然你的async generator函数实际返回的是同时实现了AsyncIterator和AsyncIterable的AsyncIterableIterator,但TypeScript会严格按照接口定义做类型检查,因此报错。

修改方案

1. 修正接口定义

把IDriver接口中tables()的返回类型从AsyncIterator<Table>改为AsyncIterableIterator<Table>(或更简洁的AsyncIterable<Table>,因为AsyncIterableIterator继承了AsyncIterable):

export interface IDriver {
  tables(): AsyncIterableIterator<Table>;
  // 或者写成:tables(): AsyncIterable<Table>;
}

2. 实现类无需额外修改

你的MySql类中async *tables()是async generator函数,它的返回类型天然就是AsyncIterableIterator<Table>,完全符合修改后的接口要求,所以实现代码可以保持不变:

export class MySql implements IDriver {
  async *tables(): AsyncIterableIterator<Table> { // 这里的返回类型也可以省略,TS会自动推断
    const sql = `select table_name, table_type, table_rows 
                 from information_schema.tables 
                 where table_schema = ${this.schema} 
                 order by table_name;`

    const rows = await this.query<{
      table_name: string
      table_type: string
      table_rows: number
    }>(sql)

    for (const row of rows) {
      yield {
        name: row.table_name,
        rows: row.table_rows,
        type: row.table_type
      } as Table
    }
  }
}

3. 兼容方案(无需修改接口)

如果因为某些原因不能修改接口,可以手动把AsyncIterator包装成AsyncIterable再使用:

const tableIterator = mysql.tables();
const tableIterable = {
  [Symbol.asyncIterator]() {
    return tableIterator;
  }
};

for await (const it of tableIterable) {
  print(it);
}

为什么不需要core-js

你提到的旧方案(引入core-js/shim)是针对早期JS环境不支持AsyncIterable的情况,而TypeScript 5.5+已经完全支持现代ES语法,你的tsconfig.json也配置了target: ESNext和lib: ["ES2018.AsyncIterable"],所以问题本质是类型定义不匹配,而非环境缺失。

内容的提问来源于stack exchange,提问作者Simple Fellow

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 11:33:19