简体   繁体   中英

How to use JavaScript FileReader in a forEach loop?

 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 is a jsPDF ; Attachment is my own class with fields as indicated.

If I run the above code in debug mode and add breakpoints, the attachments array is populated as I expected. Otherwise the array ends up blank. I know there is an issue with synchronizing the looping and the the FileReader . I found the following answer

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

but I'm not sure how to apply it to my case. Any suggestions? Thanks in advance.

I reckon the main problem is, that you kill your array attachment with each loop on the one hand and on the other hand you simply missed the plural 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
        }
     });

So try it this way:

 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);
     }

Avoid variables with unnecessarily broad scopes as often as you can. function scoped variables should always be your first choice, if applicable.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM