【问题标题】:how to handle exception for promise in loop?如何处理循环中的承诺异常?
【发布时间】:2020-12-28 15:37:04
【问题描述】:

我正在下载带有 zip 文件夹的文件,但它会先下载 zip 文件夹,然后再将文件添加到 zip 文件夹对象中。如果我删除它们并从“this.UrlToPromise()”的调用中捕获块,它可以正常工作,但是当它面临来自“this.UrlToPromise()”的拒绝时,它不能正常工作。

var zip = new JSZip();
zip = this.makezip(files, zip);
zip.generateAsync({ type: "blob" }).then(function (content) {
    if (downloadName) {
        console.log('zip download one', zip);
        FileSaver.saveAs(content, downloadName + '.zip');
    } else {
        FileSaver.saveAs(content, 'All.zip');
    }
});

async makezip(files, zip, folderName = null) {
    if (folderName)
        var tempFolder = zip.folder(folderName);
    for (var i in files) {
        files[i].hasOwnProperty('file_title')
        if (!Array.isArray(files[i])) {
            if (typeof files[i]['file_title'] !== 'undefined' && typeof files[i]['file_path'] !== 'undefined') { 
                await this.urlToPromise(files[i]['file_path']).then(response=>{
                    if (!folderName)
                        zip.file(files[i]['file_title'] + '.' + returnExtFromImage(files[i]['file_path']), response, { base64: true, binary: true });
                    else
                        tempFolder.file(files[i]['file_title'] + '.' + returnExtFromImage(files[i]['file_path']), response, { base64: true, binary: true });    
                })
            }
        } else if (Array.isArray(files[i])) {
            zip = this.makezip(files[i], zip, i);
        }
    }
    return zip;
}

urlToPromise(url) {
    return new Promise(function (resolve, reject) {
        JSZipUtils.getBinaryContent(url, function (err, data) {
            if (err) {
                reject(err);
            } else {
                resolve(data);
            }
        });
    });
}

【问题讨论】:

  • 异常处理并不是真正的问题,而是您没有等待该循环中的任何承诺。
  • 是的,你是对的,这就是问题所在,但我应用了不同的代码,但没有工作,你能分享示例代码吗?
  • 您尝试了哪些代码?异步循环通常需要awaitPromise.all
  • 我已经使用 awaita 和 async 更新了代码,现在它会生成错误“zip.generateAsync 不是函数”
  • makezip 现在正在返回一个承诺

标签: javascript reactjs promise


【解决方案1】:

每当你在 Promise 构造函数中使用 reject 时,它都会触发 Promise 实例的 catch 方法。因此,您需要在调用 urlToPromise 时添加一个 catch 处理程序,如下所示:

this.urlToPromise(files[i]['file_path']).then(response=>{
    if (!folderName)
        zip.file(files[i]['file_title'] + '.' + returnExtFromImage(files[i]['file_path']), response, { base64: true, binary: true });
    else
        tempFolder.file(files[i]['file_title'] + '.' + returnExtFromImage(files[i]['file_path']), response, { base64: true, binary: true });    
}).catch(error => {
    // do something with the error
})

【讨论】:

  • 之前下载的问题还是一样
  • 谢谢我已经解决了我的问题,请参阅下面的答案和/或更好的解决方案的建议
【解决方案2】:

async 函数中使用await 而不是then/catch。您可以使用try catch 语句来捕获错误。

async makezip(files, zip, folderName = null) {
  if (folderName) var tempFolder = zip.folder(folderName);
  for (var i in files) {
    files[i].hasOwnProperty('file_title');
    if (!Array.isArray(files[i])) {
      if (
        typeof files[i]['file_title'] !== 'undefined' &&
        typeof files[i]['file_path'] !== 'undefined'
      ) {
        try {
          const response = await this.urlToPromise(files[i]['file_path']);
          if (!folderName)
            zip.file(
              files[i]['file_title'] +
                '.' +
                returnExtFromImage(files[i]['file_path']),
              response,
              { base64: true, binary: true }
            );
          else
            tempFolder.file(
              files[i]['file_title'] +
                '.' +
                returnExtFromImage(files[i]['file_path']),
              response,
              { base64: true, binary: true }
            );
        } catch (error) {
          // handle error
        }
      }
    } else if (Array.isArray(files[i])) {
      zip = this.makezip(files[i], zip, i);
    }
  }
  return zip;
}

【讨论】:

    【解决方案3】:

    我正在回答我自己的问题,我正在等待递归函数。

    var zip = new JSZip();
    await this.makezip(files, zip).then(zip=>{
        zip.generateAsync({ type: "blob" }).then(function (content) {
            if (downloadName) {
                FileSaver.saveAs(content, downloadName + '.zip');
            } else {
                FileSaver.saveAs(content, 'All.zip');
            }
        });
    });
    
    async makezip(files, zip, folderName = null) {
        /*if folder name exist in props to create new nested folders*/
        if (folderName)
            var tempFolder = zip.folder(folderName);
        
        for (var i in files) {
            files[i].hasOwnProperty('file_title')
            if (!Array.isArray(files[i])) {
                if (typeof files[i]['file_title'] !== 'undefined' && typeof files[i]['file_path'] !== 'undefined') { 
                    await this.urlToPromise(files[i]['file_path']).then(response=>{
                        if (!folderName)
                            zip.file(files[i]['file_title'] + '.' + returnExtFromImage(files[i]['file_path']), response, { base64: true, binary: true });
                        else
                            tempFolder.file(files[i]['file_title'] + '.' + returnExtFromImage(files[i]['file_path']), response, { base64: true, binary: true });
    
                    }).catch(err=>{
    
                    });
                }
            }
            else if (Array.isArray(files[i])) {
                /*recursive loop for nested folders files*/
                await this.makezip(files[i], zip, i);
            }
        }
        return zip;
    }
    
    
    async urlToPromise(url) {
        return await new Promise(function (resolve, reject) {
            JSZipUtils.getBinaryContent(url, function (err, data) {
                if (err) {
                    reject(err);
                } else {
                    resolve(data);
                }
            });
        });
    }
    

    【讨论】:

      【解决方案4】:

      Promise 的使用对你有帮助。

      function sureify<T, U = Error>(promise: Promise<T>) {
        return promise
          .then((data) => [data, undefined] as [data: T, error: undefined])
          .catch((error: U | undefined) =>
            Promise.resolve([undefined, error] as [data: undefined, error: U])
          );
      }
      // Convert from Promise
      const [response, error] = await sureify(urlToPromise("url"))
      

      【讨论】:

        猜你喜欢
        • 2014-01-09
        • 2019-06-23
        • 2019-12-25
        • 2019-12-07
        • 2021-10-07
        • 2017-07-29
        • 2019-02-24
        • 2017-08-29
        • 1970-01-01
        相关资源
        最近更新 更多