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

NodeJS Discussion :

Attendre la fin d'une fonction asynchrone


Sujet :

NodeJS

  1. #1
    Membre régulier
    Homme Profil pro
    Étudiant - Développeur Web/Logiciel
    Inscrit en
    Mai 2012
    Messages
    67
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Vendée (Pays de la Loire)

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

    Informations forums :
    Inscription : Mai 2012
    Messages : 67
    Points : 80
    Points
    80
    Par défaut Attendre la fin d'une fonction asynchrone
    Bonjour,

    Actuellement, j'utilise le programme Phantomjs, afin de récupérer des pages web, et les enregistrer.
    Je possède un fichier id.txt qui contient l'id de toutes les pages que je souhaite récupérer et enregistrer.
    Les informations dans le fichier id.txt sont de cette forme :
    nomDeLaPage-id
    nomDeLaPage2-id2
    nomDeLaPage3-id3
    ....
    L'idée est donc de parcourir le fichier id.txt, et pour chaque ligne :
    • Récupérer l’identifiant
    • Ouvrir et enregistrer la page


    Voici le code :
    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
     
    var page = require('webpage').create();
    var fs = require('fs');
    var file_h = fs.open('id.txt', 'r'); // contains data like : myName-1111
    var line = file_h.readLine();
     
    while(line) {
        data = line.split("-");
        line = file_h.readLine();
        savePage(data[1]);
    }
     
    function savePage(id){
        page.open('http://www.myWebsite.com/'+id, function(){
            page.evaluate();
            fs.write("page/"+id+'.html', page.content, 'w');
        });
    }
     
    file_h.close();
    phantom.exit();
    Le problème c'est que l'ouverture et l'écriture de la page se fait dans une fonction asynchrone (si j'ai bien compris).
    J'aimerais donc pouvoir arrêter la boucle while tant que la page que je suis en train de récupérer, n'a pas été complètement récupérée et correctement enregistrée.

    Merci d'avance pour vos propositions !

  2. #2
    Membre expert
    Avatar de Golgotha
    Homme Profil pro
    Full-stack Web Developer
    Inscrit en
    Août 2007
    Messages
    1 387
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Full-stack Web Developer
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2007
    Messages : 1 387
    Points : 3 535
    Points
    3 535
    Billets dans le blog
    1
    Par défaut
    Bonjour, Voici une solution que je te propose parmi d'autre :

    Il faudrait que tu mette les ids de tes pages dans un tableau par exemple : pagesID ensuite tu déclare un index que tu positionne à zéro.
    Après tu fait une fonction qui contiens ton callback, le callback incrémente l'index et ré-appel la fonction qui le contient (c'est récursif).
    dans la fonction ton argument sera pageID[index]. j'espère que c'est assez claire... :/

  3. #3
    Rédacteur/Modérateur

    Avatar de SylvainPV
    Profil pro
    Inscrit en
    Novembre 2012
    Messages
    3 375
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2012
    Messages : 3 375
    Points : 9 944
    Points
    9 944
    Par défaut
    Une solution à base de callbacks:

    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
    var page = require('webpage').create();var fs = require('fs');
    var file_h = fs.open('id.txt', 'r'); // contains data like : myName-1111
     
    (function saveNextLine(){
        var line = file_h.readLine();
        if(line) {
            var data = line.split("-");
            savePage(data[1], saveNextLine);
        } else {
            console.log(" c'est fini ");
            file_h.close();
            phantom.exit();
        }
    })();
     
    function savePage(id, callback){
        page.open('http://www.myWebsite.com/'+id, function(){
            page.evaluate();
            fs.write("page/"+id+'.html', page.content, 'w');
            callback();
        });
    }
    Une solution encore meilleure serait d'utiliser les Promise, mais je ne sais pas si les fonctions de PhantomJS retournent des promesses. A voir avec la doc

  4. #4
    Membre régulier
    Homme Profil pro
    Étudiant - Développeur Web/Logiciel
    Inscrit en
    Mai 2012
    Messages
    67
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Vendée (Pays de la Loire)

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

    Informations forums :
    Inscription : Mai 2012
    Messages : 67
    Points : 80
    Points
    80
    Par défaut
    Citation Envoyé par Golgotha Voir le message
    Bonjour, Voici une solution que je te propose parmi d'autre :

    Il faudrait que tu mette les ids de tes pages dans un tableau par exemple : pagesID ensuite tu déclare un index que tu positionne à zéro.
    Après tu fait une fonction qui contiens ton callback, le callback incrémente l'index et ré-appel la fonction qui le contient (c'est récursif).
    dans la fonction ton argument sera pageID[index]. j'espère que c'est assez claire... :/
    Merci pour ta proposition Golgotha. Je pense que je vais utiliser les callback et m'inspirer du code livré par Sylvain du coup.

    Citation Envoyé par SylvainPV Voir le message
    Une solution à base de callbacks:

    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
    var page = require('webpage').create();var fs = require('fs');
    var file_h = fs.open('id.txt', 'r'); // contains data like : myName-1111
     
    (function saveNextLine(){
        var line = file_h.readLine();
        if(line) {
            var data = line.split("-");
            savePage(data[1], saveNextLine);
        } else {
            console.log(" c'est fini ");
            file_h.close();
            phantom.exit();
        }
    })();
     
    function savePage(id, callback){
        page.open('http://www.myWebsite.com/'+id, function(){
            page.evaluate();
            fs.write("page/"+id+'.html', page.content, 'w');
            callback();
        });
    }
    Une solution encore meilleure serait d'utiliser les Promise, mais je ne sais pas si les fonctions de PhantomJS retournent des promesses. A voir avec la doc
    Bonsoir Slyvain, merci pour ta proposition ainsi que d'avoir pris le temps de me donner un bout de code adapté avec !
    Je ne peux tester cela pour le moment, néanmoins dès que j'aurais pu voir le résultat, je te tiens au courant.

    Pour ce qui est de Promise, je ne connais pas du tout cela !

    Encore merci à vous deux !

  5. #5
    Membre régulier
    Homme Profil pro
    Étudiant - Développeur Web/Logiciel
    Inscrit en
    Mai 2012
    Messages
    67
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Vendée (Pays de la Loire)

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

    Informations forums :
    Inscription : Mai 2012
    Messages : 67
    Points : 80
    Points
    80
    Par défaut
    Citation Envoyé par SylvainPV Voir le message
    Une solution à base de callbacks:

    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
    var page = require('webpage').create();var fs = require('fs');
    var file_h = fs.open('id.txt', 'r'); // contains data like : myName-1111
     
    (function saveNextLine(){
        var line = file_h.readLine();
        if(line) {
            var data = line.split("-");
            savePage(data[1], saveNextLine);
        } else {
            console.log(" c'est fini ");
            file_h.close();
            phantom.exit();
        }
    })();
     
    function savePage(id, callback){
        page.open('http://www.myWebsite.com/'+id, function(){
            page.evaluate();
            fs.write("page/"+id+'.html', page.content, 'w');
            callback();
        });
    }
    Une solution encore meilleure serait d'utiliser les Promise, mais je ne sais pas si les fonctions de PhantomJS retournent des promesses. A voir avec la doc
    De retour !
    J'ai pu tester ton code Sylvain, malheureusement, il semble bloquer sur le premier callback.

    En effet, j'ai rajouté un petit
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    console.log("je lis une page");
    juste avant l'appel de la fonction savePage().

    Le message s'affiche une fois quand je lance le programme mais il ne se réaffiche pas (et le programme ne se termine pas).

    J'en conclue donc qu'il a doit tourner en boucle mais pas moyen de savoir à quel niveau !

    Merci d'avance pour ton/votre aide !

  6. #6
    Rédacteur/Modérateur

    Avatar de SylvainPV
    Profil pro
    Inscrit en
    Novembre 2012
    Messages
    3 375
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2012
    Messages : 3 375
    Points : 9 944
    Points
    9 944
    Par défaut
    Je n'ai pas testé ce code vu que je n'avais pas tous les éléments, donc je ne garantis pas son fonctionnement. Utilise le debugger, les breakpoints et l'avancement pas à pas pour voir d'où vient le problème. C'est bien plus efficace que des console.log par ci par là.

  7. #7
    Membre régulier
    Homme Profil pro
    Étudiant - Développeur Web/Logiciel
    Inscrit en
    Mai 2012
    Messages
    67
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Vendée (Pays de la Loire)

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

    Informations forums :
    Inscription : Mai 2012
    Messages : 67
    Points : 80
    Points
    80
    Par défaut
    C'est bon j'ai réussi !

    Voici le code final
    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
     
     
    var page = require('webpage').create();
    var fs = require('fs');
    var file_h = fs.open('id.txt', 'r');
     
    var line = file_h.readLine();
    data = line.split("-");
    console.log("Reading id : "+data[1]);
    savePage(data[1]);
     
    function savePage(id){
        console.log("\n#### READING http://www.myWebsite.com/"+ id +" ####")
        page.open('http://www.myWebsite.com/'+id, function(){
            page.evaluate(function(){
     
            });
            console.log("#### WRITING "+ id +".html ####")
            fs.write("page/"+id+'.html', page.content, 'w');
     
            line = file_h.readLine();
            if(line == ""){
                phantom.exit();
            }
            data = line.split("-");
            savePage(data[1]);
        });
    }

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

Discussions similaires

  1. attendre la fin d'une fonction
    Par stoner2008 dans le forum Réseau/Web
    Réponses: 3
    Dernier message: 19/04/2012, 15h32
  2. Attendre la fin d'une fonction avant d'en executer une autre
    Par FluidBlow dans le forum Général JavaScript
    Réponses: 7
    Dernier message: 24/07/2009, 21h46
  3. [PHP 5.0] Attendre la fin d'une fonction pour en realiser une autre
    Par keaton7 dans le forum Langage
    Réponses: 2
    Dernier message: 07/05/2009, 16h06
  4. Savoir la fin d'execution d'une fonction asynchrone
    Par winnyzeboss1 dans le forum C++
    Réponses: 9
    Dernier message: 20/03/2009, 14h46
  5. Attendre la fin d'une fonction
    Par benjhe dans le forum VB.NET
    Réponses: 4
    Dernier message: 13/12/2007, 14h44

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