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

TypeScript中FileReader readAsText异步遍历读取文件不等待问题

问题诱因

核心问题出在Array.forEach()的异步执行逻辑上:

  • forEach方法设计上不支持等待异步回调执行完成,你传入的async回调会被同步遍历触发,不会等待前一个回调内的await this.readFile()执行完成就进入下一轮循环,所有文件的读取操作会被并行发起,因此会出现先遍历完所有文件、触发所有readFile调用,之后才会陆续执行每个Promise完成后的console.log("next")的现象。
  • 你当前外层的try/catch也无法捕获到文件读取过程中抛出的异常,因为forEach不会将异步回调的异常冒泡到外层作用域。

解决方案

要实现串行读取效果,只需要将forEach替换为支持await阻塞逻辑的普通for循环,同时将update函数声明为async即可,修改后的代码如下:

修改后的update函数

// 声明为async函数
async update(event){
  console.log( event.target.files[0])
  this.files = Array.from(event.target.files)

  try{
    // 用普通for循环替代forEach实现串行等待
    for (let index = 0; index < this.files.length; index++) {
      const file = this.files[index];
      let last = index == this.files.length - 1;
      await this.readFile(file, last);
      console.log("next");
    }
    // 若需要所有文件读取完成后统一执行后续逻辑,可直接在此处调用this.next(),无需在readFile内判断last标识
    // this.next()
  } catch(e) {
    console.log(e)
  }
}

可选优化(并行读取)

如果不需要严格按照顺序读取文件,想要提升读取效率,也可以用Promise.all一次性并行处理所有文件:

async update(event){
  this.files = Array.from(event.target.files)
  try {
    const readPromises = this.files.map((file, index) => {
      return this.readFile(file, index === this.files.length - 1)
    })
    await Promise.all(readPromises)
    console.log("所有文件读取完成")
  } catch(e) {
    console.log(e)
  }
}

readFile逻辑补充说明

你当前readFile内的判断逻辑if(this.fileService.hasOwnProperty(tempName))是当服务类已存在对应属性时才读取文件内容,若你的预期是不存在该属性时才读取存储,可自行调整该判断条件,不影响异步逻辑的执行。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.13 09:45:01