2016-10-10 2 views
1

J'essaye de télécharger un tableau de fichiers en utilisant FileReader qui sont encodés en base64 et stockés dans un tableau pour un traitement ultérieur. J'ai du mal à comprendre le modèle que j'ai besoin de créer afin de m'assurer que tous les fichiers ont été téléchargés car je dois attendre que le gestionnaire d'événement onload se déclenche. Par exemple;Angular2: tableau de téléchargement asynchrone de fichiers

Si je transmets un tableau de fichiers à la fonction suivante, il résoudra la promesse avant que les fichiers ne soient réellement téléchargés.

localUploads(event) : any { 

    var response = []; 

    return new Promise(function(resolve, reject) { 

     //Retrieve all the files from the FileList object 
     var files = event.target.files; 
     var response = []; 

     if (files) { 

      for (var i=0, f; f=files[i]; i++) { 

       var r = new FileReader(); 

       r.onload = (function(f) { 

        return function(e) { 

         let contents = e.target['result']; 

         let file = { 
          name: f.name, 
          asset: contents, 
          private: false 
         }; 

         console.log('we are pushing into the array'); 
         response.push(file); 
        }; 

       })(f); 


      } 
      resolve(response); 
     } 

     r.readAsText(f); 
    }); 
} 

Quelqu'un peut-il s'il vous plaît aviser un novice?

Merci beaucoup.

Répondre

1

Il s'agit de résoudre la promesse au bon moment. Actuellement, vous le résolvez lorsque la boucle est terminée, mais cela ne signifie pas que tous les éléments ont été traités. Je ne l'ai pas utilisé FileReader, mais vous devriez être en mesure de faire quelque chose comme ceci:

localUploads(event) : any { 

    var response = []; 

    return new Promise(function(resolve, reject) { 

     //Retrieve all the files from the FileList object 
     var files = event.target.files; 
     var response = []; 

     if (files) { 

      for (var i=0, f; f=files[i]; i++) { 

       var r = new FileReader(); 
       r.onload = function(e) { // Possible clean-up? 
        let contents = e.target['result']; 

        let file = { 
         name: f.name, 
         asset: contents, 
         private: false 
        }; 

        console.log('we are pushing into the array'); 
        response.push(file); 
        if(response.length == files.length) 
        { 
         // Everything is done. Resolve the promise. 
         resolve(response); 
        } 
       }; 
       // Moved here to be able to access r and f variables 
       r.readAsText(f); 
      } 
     } 
    }); 
} 

Ou l'ancienne en utilisant $q.

var response = []; 
    var dfd = $q.defer(); 

    //Retrieve all the files from the FileList object 
    var files = event.target.files; 
    var response = []; 

    if (files) { 
     for (var i=0, f; f=files[i]; i++) { 
      var r = new FileReader(); 
      r.onload = function(e) { // Possible clean-up? 
       let contents = e.target['result']; 

       let file = { 
        name: f.name, 
        asset: contents, 
        private: false 
       }; 

       console.log('we are pushing into the array'); 
       response.push(file); 
       if(response.length == files.length) 
       { 
        // Everything is done. Resolve the promise. 
        dfd.resolve(response); 
       } 
      }; 
      // Moved here to be able to access r and f variables 
      r.readAsText(f); 
     } 
    } 
    else { 
     // Possible resolve promise here to? 
    } 
    return dfd.promise; 

Notez que vous pouvez également gérer les erreurs possibles. Si l'un des fichiers n'est pas terminé avec succès, la promesse ne sera jamais résolue.

Vous devrez peut-être résoudre la promesse en onloadend au lieu de onload. Je ne peux vraiment pas comprendre à partir du docs.

var r = new FileReader(); 
r.onload = function(e) { 
    if(response.length == files.length) 
    { 
     // Everything is done. Resolve the promise. 
     dfd.resolve(response); 
    } 
}