【问题标题】:How to use JavaScript FileReader in a forEach loop?如何在 forEach 循环中使用 JavaScript FileReader?
【发布时间】:2019-01-05 23:52:53
【问题描述】:
 let base64Data: string;
 let attachment: Attachment;  
 let blob: Blob;
 docList.forEach(([pdfDoc, title]) => {
            blob = pdfDoc.output('blob'); 
            var reader = new FileReader();
            reader.readAsDataURL(blob);
            reader.onloadend = function() {
              base64data = reader.result;
              attachment = new Attachment();
              attachment.setFilename(title);
              attachment.setContent(base64data);
              attachment.setType('application/pdf');
              attachments.push(attachment);
            }
         });

pdfDoc 是一个jsPDFAttachment 是我自己的类,带有指定的字段。

如果我在调试模式下运行上述代码并添加断点,attachments 数组会按预期填充。否则数组最终为空白。我知道同步循环和 FileReader 存在问题。我找到了以下答案

Looping through files for FileReader, output always contains last value from loop

但我不确定如何将其应用于我的案例。有什么建议?提前致谢。

【问题讨论】:

  • 你熟悉 Promise 吗?
  • 不管怎样,问题不在于 FileReader 的返回值,而是它异步读取的事实。您在数组被填充之前记录它。
  • 我听说过 Promises;不确定如何使用它们。已编辑的问题——我意识到问题是异步性。

标签: javascript typescript angular6


【解决方案1】:

我认为主要问题是,一方面你会在每个循环中杀死你的数组attachment,另一方面你只是错过了复数 s。

 let base64Data: string;
 let attachment: Attachment;  <<== plural s is missing
 let blob: Blob;

 docList.forEach(([pdfDoc, title]) => {
        blob = pdfDoc.output('blob'); 
        var reader = new FileReader();
        reader.readAsDataURL(blob);
        reader.onloadend = function() {
          base64data = reader.result;
          attachment = new Attachment(); <<== kills the array and overwrites it
          attachment.setFilename(title);
          attachment.setContent(base64data);
          attachment.setType('application/pdf');
          attachments.push(attachment); <<== never writes the value anywhere
        }
     });

所以试试这个方法:

 let attachments: Attachment; // with plural s

 docList.forEach(([pdfDoc, title]) => {
        const blob = pdfDoc.output('blob'); 
        const reader = new FileReader();
        reader.readAsDataURL(blob);
        reader.onloadend = function() {
          const base64data = reader.result;
          const attachment = new Attachment(); // without plural s
          attachment.setFilename(title);
          attachment.setContent(base64data);
          attachment.setType('application/pdf');
          attachments.push(attachment); // writes to the intended array

          // how to know when the last item was added?
          if(attachments.length === docList.length) {
              showListContent();
          }
        }
     });

     function showListContent() {
         console.log(attachments);
     }

尽可能避免使用范围过宽的变量。如果适用,函数作用域变量应该始终是您的首选。

【讨论】:

  • 所有好的建议,但仍然不完整。无法知道 attachment 何时会被此代码完全填充。
  • 点了。解决了。​​
  • @user3803175:如果它解决了您的问题,请不要忘记将此答案标记为解决方案。提前致谢。猞猁
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-07-04
  • 2020-06-17
  • 2021-01-28
  • 1970-01-01
  • 2019-11-21
  • 2023-03-27
  • 2015-05-04
相关资源
最近更新 更多