Angular: FileReader - reader 执行了太多次

Angular: FileReader - reader executes too many times

我有这个 FileReader,我可以用它读取文件夹:

private fileCache: any[];
  private folderReader$: Subject<any[]> = new Subject();

  public readFolder(files: any[]) {
    this.fileCache = [];
    this.readFile(0, files);
    return this.folderReader$.asObservable();
  }

  private readFile(index, files) {
    const reader = new FileReader();
    if (index >= files.length) {
      this.folderReader$.next(this.fileCache);
      return;
    }
    const file = files[index];
    const filename = file.name;
    reader.onload = (e: any) => {
      this.fileCache.push({
        name: filename,
        content: e.target.result});
      this.readFile(index+ 1, files);
    };

    reader.readAsText(file);
  }
}

现在奇怪的是,每当我选择第二个输入时,它都会运行多次。如果我只选择一个输入,一切都很好...

例如使用这个时:

this.folderReader.readFolder(data.target.files).subscribe(files => {
    console.log(test);
}

输入两次后,控制台会显示三次测试:

test
test
test

就像我在这里看到的那样: 可能是 onload 运行 多次的问题,所以我尝试删除这一行:

  this.readFile(index+ 1, files);

这样整个功能就不会重新开始了... 但是,在那之后,它根本不起作用,因为它可能需要 index+1 以便它可以遍历我认为的所有文件。

我在这里做错了什么?为什么 FileReader 每次输入执行多次而不是一次?

这是你处理主题的方式。

一种解决方法是在 readFolder 调用中重新初始化您的主题,例如:

  public readFolder(files: any[]) {
    this.folderReader$ = new Subject();
    this.fileCache = [];
    this.readFile(0, files);
    return this.folderReader$.asObservable();
  }

但更好的方法是使用另一个 Subject,例如 rxjs 中的 BehaviorSubject。

看看Understanding rxjs BehaviorSubject, ReplaySubject and AsyncSubject