машинопись для каждого асинхронного вызова метода на l oop завершена - PullRequest
0 голосов
/ 13 февраля 2020

Я использую Angular 8 .

Существует служба download, которая загружает несколько файлов из URL в формате zip с использованием библиотеки JSZip.

Метод

  public multi(fileList: Array<string>, fileName: string = 'File') {
    const zip: JSZip = new JSZip();

    // Reset downloadErrors object
    this.downloadErrors = {
      errorCount: 0,
      files: []
    };

    return new Promise((resolve, reject) => {
      fileList.forEach((d, idx) => {

        JSZipUtils.getBinaryContent(d, (error: Error, data) => {

          if (error) {
            this.downloadErrors.errorCount += 1;
            this.downloadErrors.files.push({
              file: DownloadService.getFileName(d),
              error: error.message
            });
          }

          if (data) {
            console.log('Adding file: ', data);
            zip.file(DownloadService.getFileName(d), data, {binary: true});
          }

          if (idx === fileList.length - 1) {
            if (this.downloadErrors.errorCount !== fileList.length) {
              zip.generateAsync({
                type: 'blob',
                mimeType: 'application/octet-stream'
              }).then(content => {
                this.createLinkAndDownload(URL.createObjectURL(content), `${fileName}.zip`);

                if (this.downloadErrors.errorCount > 0) {
                  reject({
                    typ: 'warning',
                    message: `${this.downloadErrors.errorCount} files couldn't be downloaded`
                  });
                  console.error(`Error downloading ${this.downloadErrors.errorCount} files: `, this.downloadErrors.files);
                } else {
                  resolve();
                }
              });
            } else {
              reject(new Error('Zip file could not be downloaded'));
              console.error(`Error downloading ${this.downloadErrors.errorCount} files: `, this.downloadErrors.files);
            }
          }
        });
      });
    });
  }

Использование JSZipUtils.getBinaryContent для получения данных с URL-адреса и добавления полученных данных к объекту zip.

Для загрузки zip файл, когда l oop завершен, я вызываю метод, который создает гиперссылку и запускает загрузку zip-файла, когда индекс l oop удовлетворяет условию

if (idx === fileList.length - 1) {}

Теперь, поскольку JSZipUtils.getBinaryContent() извлекает контент для каждого URL-адреса с сервера, это занимает некоторое время, но forEach l oop завершает обход каждого файла независимо от завершения вызова getBinaryContent. Следовательно, загрузка запускается даже тогда, когда выполняется небольшое количество вызовов getBinaryContent.

Это приводит к повреждению загрузки zip или отсутствию файлов из загруженного файла zip.

Как это проблема может быть решена?

...