IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

JavaScript Discussion :

FileReader() attendre la fin de chargement d'un fichier text


Sujet :

JavaScript

  1. #1
    Membre à l'essai
    Homme Profil pro
    Inscrit en
    Août 2011
    Messages
    28
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Août 2011
    Messages : 28
    Points : 19
    Points
    19
    Par défaut FileReader() attendre la fin de chargement d'un fichier text
    Bonjour,

    Dans le code ci-dessous, il y a deux fonctions : main() et file_uploaded().

    Après que l'utilisateur ait choisi le ou les fichiers à charger, la fonction main() va lancer la fonction file_uploaded() pour que les données des fichiers text se retrouvent au bon format dans le tableau "tableau_data".
    Ensuite, elle lance d'autres fonctions qui vont travailler à partir des données qui sont dans tableau_data.

    Cependant, les données n'ont pas le temps d'être chargées dans tableau_data que les fonctions function a() et function b() sont déjà lancées. Donc forcément, il y a des erreurs qui apparaissent.

    Je cherche donc un moyen d'attendre la fin du chargement du fichier text avant que les autres fonctions soient lancées.

    Code HTML : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    <html>
    <head>
    	<title>Lire fichier</title>	
    </head>
    <body>
        <form>
    		<input id="dataFile" type="file" accept=".txt" multiple/></input>
        </form>
    	<script>
     
                    //Déclaration  des variables
                    let tableau_data = [];
                    let datafile;
                    let n = 1;
                    
                    
                    let input = document.querySelector('input');
                    // let preview = document.querySelector('.preview');
                    input.addEventListener('change', main);
                    
                    
                    function file_uploaded(datafile){
                            //Cette fonction permetTant de charger un fichier
                            let reader = new FileReader();
                            
                            reader.onload = function(event) {
                                            let records = reader.result.split("\r\n");
                                            //mise en forme du tableau de données
                                            mise_en_forme_donnees(records,";");
                                            records.forEach(function(element) {
                                                    tableau_data.push(element.split("="));
                                            });                     
                            };                              
                            reader.readAsText(datafile);    
                    }
                    
     
                    function main() {
                            // fonction principale
                            
                            n = document.getElementById("dataFile").files.length; // récupère le nombre de document à charger
                            
                            
                            for (var i = 0; i < n; i ++){
                                    datafile = document.getElementById("dataFile").files[i];
                                    file_uploaded(datafile); // lance la fonction de chargement du fichier.
                                    
                                    function a(tableau_data);
                                    function b(tableau_data);
                            }
                    }
     
            </script>
    </body>
     
    </html>

    Je vous remercie par avance pour votre aide.

    Yu Cloud

  2. #2
    Rédacteur/Modérateur

    Avatar de SpaceFrog
    Homme Profil pro
    Développeur Web Php Mysql Html Javascript CSS Apache - Intégrateur - Bidouilleur SharePoint
    Inscrit en
    Mars 2002
    Messages
    39 636
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 74
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Développeur Web Php Mysql Html Javascript CSS Apache - Intégrateur - Bidouilleur SharePoint
    Secteur : Industrie

    Informations forums :
    Inscription : Mars 2002
    Messages : 39 636
    Points : 66 655
    Points
    66 655
    Billets dans le blog
    1
    Par défaut
    Un ajax sur le fichier texte ?
    Ma page Developpez - Mon Blog Developpez
    Président du CCMPTP (Comité Contre le Mot "Problème" dans les Titres de Posts)
    Deux règles du succès: 1) Ne communiquez jamais à quelqu'un tout votre savoir...
    Votre post est résolu ? Alors n'oubliez pas le Tag

    Venez sur le Chat de Développez !

  3. #3
    Expert confirmé Avatar de psychadelic
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    2 529
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2010
    Messages : 2 529
    Points : 4 739
    Points
    4 739
    Par défaut
    normalement un événement 'loadend' est déclenché en fin de lecture, que ce soit ou non "bien passé" et que le gestionnaire en est finit sur la lecture d'un fichier

    pour la suite l'utilisation des promesses peut être utile.
    «La pluralité des voix n'est pas une preuve, pour les vérités malaisées à découvrir, tant il est bien plus vraisemblable qu'un homme seul les ait rencontrées que tout un peuple.» [ René Descartes ] - Discours de la méthode

  4. #4
    Membre à l'essai
    Homme Profil pro
    Inscrit en
    Août 2011
    Messages
    28
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Août 2011
    Messages : 28
    Points : 19
    Points
    19
    Par défaut
    Le fichier que je souhaite lire est sur le pc de l'utilisateur et je ne souhaite pas le charger sur le serveur pour le lire ensuite.
    Donc je pense que l'AJAX n'est pas adapté à la fonction que je souhaite réaliser.

    J'ai pensé à mettre .addEventListener("loadend", function a) par exemple, ce qui m'aurait permis d'attendre le chargement du fichier pour lancer la fonction mais ça aurait bien fonctionné si j'avais uniquement 1 fichier à charger. Cependant, je boucle sur plusieurs fichiers et la lecture du fichier suivant est lancée avant même que le précédent ne soit chargé !

    J'ai également essayé la propriété .onloadend de FileReader() mais elle renvoie toujours null quelque soit la position où je mets le console.log pour observer l'état d'avancement du chargement du fichier.

    Je ne vois pas comment récupérer l'état du chargement et faire en sorte que le programme attende la fin du chargement avant de lancer les autres fonctions.

  5. #5
    Membre éclairé
    Femme Profil pro
    Autre
    Inscrit en
    Janvier 2017
    Messages
    335
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Autre

    Informations forums :
    Inscription : Janvier 2017
    Messages : 335
    Points : 715
    Points
    715
    Par défaut
    Bonjour,
    Si j'ai bien compris, par rapport au code existant, le plus simple serait d'ajouter, à la fin de la fonction reader.onload = function(event) {}, ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    if(--n===0) {
    	a(tableau_data);
    	b(tableau_data);
    }

  6. #6
    Expert confirmé Avatar de psychadelic
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    2 529
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2010
    Messages : 2 529
    Points : 4 739
    Points
    4 739
    Par défaut
    Sinon, pourquoi parler d'Ajax? quel rapport ?
    «La pluralité des voix n'est pas une preuve, pour les vérités malaisées à découvrir, tant il est bien plus vraisemblable qu'un homme seul les ait rencontrées que tout un peuple.» [ René Descartes ] - Discours de la méthode

  7. #7
    Expert éminent sénior

    Homme Profil pro
    Développeur Web
    Inscrit en
    Septembre 2010
    Messages
    5 380
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Septembre 2010
    Messages : 5 380
    Points : 10 410
    Points
    10 410
    Par défaut
    Citation Envoyé par psychadelic Voir le message
    comme je l'ai écrit plus haut, utilise les promesses, et ici en l’occurrence il faut caser un Promise.all() englobant chacune des lectures
    Je ne pense pas que cela soit nécessaire ici. A priori le code de Loralina devrait fonctionner correctement.

  8. #8
    Expert confirmé Avatar de psychadelic
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    2 529
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2010
    Messages : 2 529
    Points : 4 739
    Points
    4 739
    Par défaut
    oui effectivement l'idée de Loralina est la bonne, ce qui donne :

    Code javascript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    const ihm_input    = document.querySelector('#dataFile')
    var   tableau_data = []
     
    ihm_input.onchange =_=>
      {
      let countFicLu = ihm_input.files.length
     
      for(let inFile of ihm_input.files)
        {
        let reader = new FileReader()
        reader.onload =_=>
          {
          let records = reader.result.split('\n')
          for(let line of records)
            {
            tableau_data.push(line.split('='))
            }
          if(!--countFicLu)
            {  
            fct_a()
            fct_b()
            }
          }
        reader.readAsText(inFile); 
        }
      }
    function fct_a()
      {
      console.log( tableau_data )
      }
    function fct_b()
      {
      console.log( 'fct b' )
      }
    «La pluralité des voix n'est pas une preuve, pour les vérités malaisées à découvrir, tant il est bien plus vraisemblable qu'un homme seul les ait rencontrées que tout un peuple.» [ René Descartes ] - Discours de la méthode

  9. #9
    Rédacteur/Modérateur

    Avatar de SpaceFrog
    Homme Profil pro
    Développeur Web Php Mysql Html Javascript CSS Apache - Intégrateur - Bidouilleur SharePoint
    Inscrit en
    Mars 2002
    Messages
    39 636
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 74
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Développeur Web Php Mysql Html Javascript CSS Apache - Intégrateur - Bidouilleur SharePoint
    Secteur : Industrie

    Informations forums :
    Inscription : Mars 2002
    Messages : 39 636
    Points : 66 655
    Points
    66 655
    Billets dans le blog
    1
    Par défaut
    C'est moi qui avait proposé un ajax pour utiliser le success ou le done.
    Mais au vu que le fichier est sur le poste client ce n'est en effet pas adapté.
    Je dirais même que lire un fichier sur le poste du client n'est pas forcément une bonne idée...
    Ma page Developpez - Mon Blog Developpez
    Président du CCMPTP (Comité Contre le Mot "Problème" dans les Titres de Posts)
    Deux règles du succès: 1) Ne communiquez jamais à quelqu'un tout votre savoir...
    Votre post est résolu ? Alors n'oubliez pas le Tag

    Venez sur le Chat de Développez !

  10. #10
    Membre à l'essai
    Homme Profil pro
    Inscrit en
    Août 2011
    Messages
    28
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Août 2011
    Messages : 28
    Points : 19
    Points
    19
    Par défaut
    Merci pour vos réponses.

    Citation Envoyé par psychadelic
    Sinon, pourquoi parler d'Ajax? quel rapport ?
    C'était pour répondre à la proposition de SpaceFrog.

    En effet quand on est dans reader.onload = function(e){ code };, les fonctions function a() et function b() sont exécutées après le chargement du fichier texte.
    Donc les propositions de Loralina et psychadelic fonctionnent mais obligent à ce que tout le traitement soit fait dans le reader.onload.

    J'aurais aimé avoir une fonction principale qui lance toutes les fonctions dont la fonction file_uploaded().
    D'où mon besoin initial de pouvoir attendre que les fichiers soient chargés avant de lancer les autres fonctions.

  11. #11
    Membre éclairé
    Femme Profil pro
    Autre
    Inscrit en
    Janvier 2017
    Messages
    335
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Autre

    Informations forums :
    Inscription : Janvier 2017
    Messages : 335
    Points : 715
    Points
    715
    Par défaut
    Bonjour,
    Citation Envoyé par Yu Cloud Voir le message
    J'aurais aimé avoir une fonction principale qui lance toutes les fonctions dont la fonction file_uploaded().
    Ce serait possible avec await, mais bon, je trouve que cette fonction "main" aurait un petit aspect fourre-tout.

    Donc les propositions de Loralina et psychadelic fonctionnent mais obligent à ce que tout le traitement soit fait dans le reader.onload.
    Les fonctions "a" et "b" sont certes appelées depuis cette fonction "onload", mais leur exécution se déroule relativement au contexte où elles sont définies.

    Après, rien n'empêche de faire if(--n===0){quandFichiersCharges();} et, dans la fonction "quandFichiersCharges", on exécute les fonctions "a" et "b".
    La fonction "main" pourrait d'ailleurs être renommée en "chargerFichiers".
    Il n'est pas plus mal de bien séparer les tâches, plutôt que d'avoir une seule fonction "main".

    Dans la fonction "onload", on en met aussi peu que nécessaire.
    On pourrait justement concevoir le programme indépendamment de l'origine des textes :
    Les textes pourraient venir de fichiers locaux, distants ou de simples variables js.
    Dans cette optique, on pourrait avoir une fonction "traiterTexte", et le "onload" ferait uniquement : {traiterTexte(this.result);if(--n===0){quandFichiersCharges();}
    Même si concrètement les textes proviennent uniquement de fichiers locaux, conceptualiser la chose de manière un peu plus générale apporte souvent un plus.


    En effet quand on est dans reader.onload = function(e){ code };, les fonctions function a() et function b() sont exécutées après le chargement du fichier texte.
    Avec la condition if(--n===0), les fonctions "a" et "b" sont appelées une seule fois et quand tous les fichiers sont chargés, et non pas à chaque fin de chargement de fichier.

    D'où mon besoin initial de pouvoir attendre que les fichiers soient chargés avant de lancer les autres fonctions.
    Oui, comme je viens de le préciser, c'est le cas avec la condition if(--n===0).

  12. #12
    Membre éclairé
    Femme Profil pro
    Autre
    Inscrit en
    Janvier 2017
    Messages
    335
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Autre

    Informations forums :
    Inscription : Janvier 2017
    Messages : 335
    Points : 715
    Points
    715
    Par défaut
    Citation Envoyé par Loralina Voir le message
    Si j'ai bien compris
    Après relecture, je me demande si j'ai bien compris : les fonctions "a" et "b" doivent être lancées après chaque fin de chargement de fichier ou bien une seule fois quand tout est fini ?
    A la limite, peu importe, mes remarques donnent des pistes pour les deux cas de figure.

    A noter cette variante classique qui consiste à charger les fichiers un à un : on charge le premier fichier, puis une fois chargé, on charge le deuxième et ainsi de suite.

  13. #13
    Expert confirmé Avatar de psychadelic
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    2 529
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2010
    Messages : 2 529
    Points : 4 739
    Points
    4 739
    Par défaut
    Citation Envoyé par Yu Cloud Voir le message
    Merci pour vos réponses.
    J'aurais aimé avoir une fonction principale qui lance toutes les fonctions dont la fonction file_uploaded().
    D'où mon besoin initial de pouvoir attendre que les fichiers soient chargés avant de lancer les autres fonctions.
    Dans ce cas la, si tu veux avoir des fonctions séparées pour chaque type de traitement et jouer sur la synchronisation, faut utiliser les Promesses (comme indiqué dans mon premier post).

    j'ai préféré encapsuler les parties FileReader, d'autant plus que c'est dedans que ce passe la gestion des promesses..
    Code javascript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    // déclarations..
     
    const evtFinishAllLoading = new Event('FilesLoaded')
        , ihm_input           = document.querySelector('#dataFile')
    var   tableau_data        = []
     
    document.addEventListener('FilesLoaded', fct_4_files_loaded)
     
    const myFileLoader=
      { async getInFiles(InputIHM, EndingEvt, fctChargement )
          {
          for(let FileIn of InputIHM.files)
            {
            await this.read_1_file(FileIn, fctChargement)
            }
          document.dispatchEvent(EndingEvt) 
          }
      , read_1_file(inFile, fctChargement)
          {
          return new Promise(resolve=>
            {
            let reader = new FileReader()
            reader.onload =_=> { fctChargement(reader, resolve) }
            reader.readAsText(inFile)
            }) 
          }
      }
     
    ihm_input.onchange=_=>{ myFileLoader.getInFiles(ihm_input, evtFinishAllLoading, Charge_tableau_data) }
     
     
    // traitements métier //
     
    function Charge_tableau_data(fileTxt, fctEnd)
      {
      for(let line of fileTxt.result.split('\n') )
        {
        tableau_data.push(line.split('='))
        }
      fctEnd()
      }
     
    function fct_4_files_loaded()
      {
      fct_a()
      fct_b()
      }
     
     
    // fcts de fin de traitement...
    function fct_a()
      {
      console.log( tableau_data )
      }
    function fct_b()
      {
      console.log( 'fct b' )
      }
    «La pluralité des voix n'est pas une preuve, pour les vérités malaisées à découvrir, tant il est bien plus vraisemblable qu'un homme seul les ait rencontrées que tout un peuple.» [ René Descartes ] - Discours de la méthode

  14. #14
    Membre à l'essai
    Homme Profil pro
    Inscrit en
    Août 2011
    Messages
    28
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Août 2011
    Messages : 28
    Points : 19
    Points
    19
    Par défaut
    Citation Envoyé par Loralina Voir le message
    Après relecture, je me demande si j'ai bien compris : les fonctions "a" et "b" doivent être lancées après chaque fin de chargement de fichier ou bien une seule fois quand tout est fini ?
    Les fonctions "a" et "b" sont lancées après chaque fin de chargement.

    Citation Envoyé par Loralina Voir le message
    Ce serait possible avec await, mais bon, je trouve que cette fonction "main" aurait un petit aspect fourre-tout.
    Citation Envoyé par Loralina Voir le message
    Il n'est pas plus mal de bien séparer les tâches, plutôt que d'avoir une seule fonction "main".
    Avec la fonction main, je cherche justement à bien séparer les tâches... Chaque fonction a un rôle et celui de file_uploaded() est de charger les fichiers pour pouvoir ensuite utiliser les fonctions de traitement.
    Il me semble que mettre les fonctions de traitement dans le reader.onload revient à transformer file_uploaded() en fonction principale...

    Dans tous les cas, il apparaît que je dois changer la structure d'exécution des fonctions soit en les intégrant dans reader.onload soit en utilisant les promesses.

  15. #15
    Membre éclairé
    Femme Profil pro
    Autre
    Inscrit en
    Janvier 2017
    Messages
    335
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Autre

    Informations forums :
    Inscription : Janvier 2017
    Messages : 335
    Points : 715
    Points
    715
    Par défaut
    Bonjour,
    psychadelic vient justement de faire un exemple avec await.
    Si besoin, await peut être intégré facilement au code de départ (ce sera peut-être plus simple pour s'y retrouver dans un premier temps) :
    - Faire await file_uploaded(datafile);
    - Dans file_uploaded, faire un return new Promise... avec un resolve() dans le onload.
    Il n'y a qu'à copier-coller l'exemple de la page dont j'ai mis le lien ou bien celui de psychadelic.

    Citation Envoyé par Yu Cloud Voir le message
    Avec la fonction main, je cherche justement à bien séparer les tâches...
    Elles sont peut-être séparées dans la présentation, mais au final regroupées dans la même fonction...

    En quoi est-ce mieux de vouloir lancer les chargements et gérer la suite des traitements dans la même fonction ?
    C'est juste pour avoir une sorte de scénario regroupé au même endroit ?

    Il me semble qu'on peut séparer cela en quelques fonctions et avoir un code très lisible au final.

    Bien sûr, avec await on peut s'en sortir avec une fonction (sous réserve d'un peu plus de code par ailleurs), et j'encourage à tester la chose, mais il me paraît également intéressant de savoir structurer différemment les choses pour s'en sortir autrement et d'une manière plus universelle :
    1) Appeler une fonction qui charge les fichiers.
    2) A chaque fin de chargement, appeler une fonction qui traite ou mémorise le texte.
    3) Une fois tout chargé, appeler une fonction qui effectue un traitement final ou enchaîne sur la suite.

    Il y a un moyen de faire un code simple et clair avec ça.

    Citation Envoyé par Yu Cloud Voir le message
    Il me semble que mettre les fonctions de traitement dans le reader.onload revient à transformer file_uploaded() en fonction principale...
    Je ne trouve pas.
    Il ne s'agit pas de mettre les fonctions dans le onload, mais juste de les appeler.
    Il ne s'agit pas non plus d'écrire plein d'instructions et d'appeler plein de fonctions dans le onload, mais d'en sortir le plus rapidement possible et de confier la suite du traitement au gestionnaire concerné (c'est l'idée, car ici il n'y en a pas vraiment dans le code actuel), un peu comme ceci :
    onload=function(){traiterTexte(this.result);}
    La fonction "traiterTexte" n'aurait même pas forcément besoin de savoir d'où vient le texte et pourrait fonctionner avec d'autres origines.

    Il y a de nombreuses approches possibles, autant en tester quelques-unes pour mieux en apprécier les avantages et inconvénients.

    Citation Envoyé par Yu Cloud Voir le message
    Les fonctions "a" et "b" sont lancées après chaque fin de chargement.
    D'accord, du coup j'avais orienté la suite de la conversation sur une mauvaise piste.
    Malgré tout, je pense que tous les éléments de réponses apportés permettent de débloquer la situation.

  16. #16
    Expert confirmé Avatar de psychadelic
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    2 529
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2010
    Messages : 2 529
    Points : 4 739
    Points
    4 739
    Par défaut
    Citation Envoyé par Yu Cloud Voir le message
    Les fonctions "a" et "b" sont lancées après chaque fin de chargement.
    c'est pas du tout ce que j'avais compris

    donc à chaque fois qu'un fichier de la liste est lu, et a rempli la table tableau_data , il faut lancer les fonctions A et B ?

    mais dans ce cas, comme la table s'agrandi des nouvelles données lues par chaque fichier, les fonctions vont retraiter les mêmes données précédemment traitées par les lectures des fichiers précédents.. !

    c'est pas très logique !

    [edit]
    en imaginant qu'il y ait une logique ici, cela implique de mettre la fonction englobante (des appels des fonctions A et B) sous forme de promesse elle aussi, mais si les fonctions qu'elle appelle sont asynchrone, alors il faut aussi les placer chacune dans une promesse.

    ça devient un peu délirant.
    «La pluralité des voix n'est pas une preuve, pour les vérités malaisées à découvrir, tant il est bien plus vraisemblable qu'un homme seul les ait rencontrées que tout un peuple.» [ René Descartes ] - Discours de la méthode

  17. #17
    Expert éminent sénior

    Homme Profil pro
    Développeur Web
    Inscrit en
    Septembre 2010
    Messages
    5 380
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Septembre 2010
    Messages : 5 380
    Points : 10 410
    Points
    10 410
    Par défaut
    Citation Envoyé par Yu Cloud Voir le message
    Avec la fonction main, je cherche justement à bien séparer les tâches... Chaque fonction a un rôle et celui de file_uploaded() est de charger les fichiers pour pouvoir ensuite utiliser les fonctions de traitement.
    Il me semble que mettre les fonctions de traitement dans le reader.onload revient à transformer file_uploaded() en fonction principale...

    Dans tous les cas, il apparaît que je dois changer la structure d'exécution des fonctions soit en les intégrant dans reader.onload soit en utilisant les promesses.
    Comme dit Loralina plus haut, tu ne mets pas ces fonctions dans le reader, mais tu les appelle depuis le reader pour exploiter l'événement onload. Après tu peux aussi passer les fonctions en paramètre dans ta fonction si tu veux mieux voir ce que tu fais depuis ta fonction main :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
     
    //...
    function file_execute(datafile, f1, f2, f3 ){
                            //Cette fonction permet  de charger un fichier et d'exécuter les fonctions f1, f2 et f3
                            let reader = new FileReader();
                            reader.onload = function(event) {
                                            //mise en forme avec f1
                                            let tab = f1(reader.result);
     
                                            // exécute les autres fonctions passées en paramètre en utilisant le résultat de la première
                                            f2(tab);
                                            f3(tab);             
                            };                              
                            reader.readAsText(datafile);    
                    }
     
     
    function main() {
                            // fonction principale
     
                            var mise_en_forme = function(fichier) {
                                   let records = fichier.split("\r\n");
                                   //mise en forme du tableau de données
                                   //mise_en_forme_donnees(records,";");
                                   records.forEach(function(element) {
                                   tableau_data.push(element.split("="));
                                   });
                                   return tableau_data;
                             }
     
                            var a = function (tab_data) {
                             console.log('fonction a '+tab_data);
                            };
     
                            var b = function (tab_data) {
                            console.log('fonction b '+tab_data);
                            };
     
     
                            n = document.getElementById("dataFile").files.length; // récupère le nombre de document à charger    
                            for (var i = 0; i < n; i ++){
                                    datafile = document.getElementById("dataFile").files[i];
                                    file_execute(datafile, mise_en_forme, a, b ); // lance la fonction de chargement du fichier et exécute les fonctions "mise_en_forme", "a" et "b" (tu pourrais aussi regrouper ces trois fonctions en une seule fonction)
                            }
                    }
    Sinon, si tu ne veux pas exploiter directement l'événement onload, il te faudra utiliser des promesses mais autant les éviter si tu veux un code le plus optimisé et le plus universel possible (compatible avec les versions IE antérieures à Edge).

  18. #18
    Membre à l'essai
    Homme Profil pro
    Inscrit en
    Août 2011
    Messages
    28
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Août 2011
    Messages : 28
    Points : 19
    Points
    19
    Par défaut
    Citation Envoyé par psychadelic Voir le message
    c'est pas du tout ce que j'avais compris

    donc à chaque fois qu'un fichier de la liste est lu, et a rempli la table tableau_data , il faut lancer les fonctions A et B ?

    mais dans ce cas, comme la table s'agrandi des nouvelles données lues par chaque fichier, les fonctions vont retraiter les mêmes données précédemment traitées par les lectures des fichiers précédents.. !

    c'est pas très logique !
    Je réinitialise tableau_data avant de passer au fichier suivant. Ainsi les fonctions "a" et "b" sont lancées après chaque lecture de fichier mais tableau_data est réinitialisé après que le traitement sur les données soit fait.
    En effet, une fois que les données sont traitées, je les stocke dans tableau_data_final.

    Citation Envoyé par Loralina Voir le message
    Bien sûr, avec await on peut s'en sortir avec une fonction (sous réserve d'un peu plus de code par ailleurs), et j'encourage à tester la chose, mais il me paraît également intéressant de savoir structurer différemment les choses pour s'en sortir autrement et d'une manière plus universelle :
    1) Appeler une fonction qui charge les fichiers.
    2) A chaque fin de chargement, appeler une fonction qui traite ou mémorise le texte.
    3) Une fois tout chargé, appeler une fonction qui effectue un traitement final ou enchaîne sur la suite.
    C'est justement ce que j'essaie de faire avec la fonction main. Tout d'abord on charge les fichiers, puis une fois que le chargement est fini, on appelle les fonctions qui traitent et mémorisent pour finir par un post-traitement des données mémorisées.
    Cela me paraissait plus clair de faire le déroulement dans une fonction dédiée...

    J'ai réussi à faire fonctionner mon code avec await et les promesses.

    Code javascript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
     
    //Déclaration  des variables
    let tableau_data = [];
    let tableau_data_final = [];
    let datafile;
    let n = 1;
     
     
    let input = document.querySelector('input');
    // let preview = document.querySelector('.preview');
    input.addEventListener('change', main);
     
     
    function fileUploaded(datafile){
    	return new Promise(resolve => {
    		 let reader = new FileReader();
     
    		reader.onload = function(event) {
    			Charge_tableau_data(reader, resolve);					
    		};				
    		reader.readAsText(datafile);
    	});
    }
     
    function Charge_tableau_data(fileTxt, fctEnd){
    	for (let line of fileTxt.result.split('\r\n') ){
    		if (line.endsWith(";")) {
    			line = line.substring(0, line.length - 1);
    		}
    		tableau_data.push(line.split('='));
    	}
    	fctEnd();
    }
     
    async function main() {
    	// fonction principale
     
    	n = document.getElementById("dataFile").files.length; // récupère le nombre de document à charger
     
     
    	for (var i = 0; i < n; i ++){
    		datafile = document.getElementById("dataFile").files[i];
    		await file_uploaded(datafile); // lance la fonction de chargement du fichier.
     
    		function a(tableau_data);
    		function b(tableau_data);
    		tableau_data = [];
    	}
    }

    Merci beaucoup psychadelic et Loralina pour votre aide. Cet échange a été fort instructif.
    Merci également aux autres membres qui ont participé.

    Par la suite, je vais essayer de modifier le code pour qu'il soit plus lisible.

    Bonne journée

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [Process] comment attendre la fin du chargement?
    Par elflamby dans le forum VB.NET
    Réponses: 1
    Dernier message: 03/04/2007, 16h04
  2. [FLASH MX2004] [AS2] Attendre la fin de chargement d'un fichier avant de continuer.
    Par Demco dans le forum ActionScript 1 & ActionScript 2
    Réponses: 6
    Dernier message: 01/03/2007, 16h13
  3. Attendre la fin du chargement d'un clip
    Par arnaud_verlaine dans le forum Flash
    Réponses: 5
    Dernier message: 13/09/2006, 12h39
  4. attendre la fin de chargement d'une page avant de continuer le script
    Par jibouze dans le forum Général JavaScript
    Réponses: 5
    Dernier message: 07/06/2006, 10h50
  5. Attendre la fin du chargement de la page dans un WebBrowser
    Par core1 dans le forum Web & réseau
    Réponses: 5
    Dernier message: 15/06/2003, 05h12

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo