Как обернуть FileSystemFileEntry.file в функцию, которая возвращает Observable? - PullRequest
0 голосов
/ 07 ноября 2018

Я пытаюсь рекурсивно читать файлы из удаленной папки.

onDrop(event) {
  event.preventDefault();
  this.folderData = [];
  this.filesData = [];

    const items = event.dataTransfer.items;
    for (let i = 0; i < items.length; i++) {
      const item = items[i].webkitGetAsEntry();
      if (item) {
        this.scanFiles(item, this.folderData);
      }
    }
    // send out data
    // this.dropped.emit({ folderData: this.folderData, filesData: this.filesData });
}

private scanFiles(item, container: Array<any>) {
  const nodeData = {
    name: item.name,
    isDirectory: item.isDirectory,
    item: item,
    children: []
  };

  container.push(nodeData);
  if (item.isDirectory) {
    const directoryReader = item.createReader();
    directoryReader.readEntries(entries => {
      if (entries) {
        entries.forEach(entry => this.scanFiles(entry, nodeData.children));
      }
    });
  } else if (item.isFile) {
    // How to return an Observable array here? 
    item.file(file => {
      file.fullPath = item.fullPath;
      this.filesData.push(file);
    });
  }

}

Согласно MDN, FileSystemFileEntry.file возвращает результат в обратном вызове. https://developer.mozilla.org/en-US/docs/Web/API/FileSystemFileEntry/file

Таким образом, прежде чем onDrop отправит результат, он должен дождаться завершения всех обратных вызовов FileSystemFileEntry.file.

Я хочу использовать Observable.forkJoin для достижения этой цели. Но перед этим, как обернуть FileSystemFileEntry.file в функцию, которая возвращает Observable?

1 Ответ

0 голосов
/ 07 ноября 2018

Оказывается, что один forkJoin не может решить проблему. Я наконец завершаю это с помощью рекурсивного forkJoin.

onDrop(event) {
  event.preventDefault();
  this.folderData = [];
  this.filesData = [];

  const items = event.dataTransfer.items;
  const obs = [];
  for (let i = 0; i < items.length; i++) {
    const item = items[i].webkitGetAsEntry();
    if (item) {
      obs.push(new Observable<any>(observer => this.scanFiles(item, this.folderData, observer)));
    }
  }

  forkJoin(obs).subscribe(e => {
    this.dropped.emit({ folderData: this.folderData, filesData: this.filesData });
  });
}

private scanFiles(item, container: Array<any>, observer: Subscriber<any>) {
const nodeData = {
  name: item.name,
  isDirectory: item.isDirectory,
  item: item,
  children: []
};

container.push(nodeData);
if (item.isDirectory) {
  const directoryReader = item.createReader();
  directoryReader.readEntries(entries => {
    if (entries) {
      if (entries.length === 0) {
        observer.next();
        observer.complete();
      } else {
        const subObs = entries.map(entry => new Observable<any>(innerObserver =>
          this.scanFiles(entry, nodeData.children, innerObserver)));
        forkJoin(subObs).subscribe(e => {
          observer.next();
          observer.complete();
        });
      }
    } else {
      observer.next();
      observer.complete();
    }
  });
} else if (item.isFile) {
  item.file(file => {
      file.fullPath = item.fullPath;
      this.filesData.push(file);
      observer.next();
      observer.complete();
  });
}

}

Для дополнительной проверки https://github.com/ft115637850/ngx-folder-uploader.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...