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 :

asynchrone synchrone attente fin de boucle


Sujet :

NodeJS

  1. #1
    Membre confirmé
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Octobre 2002
    Messages
    80
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Administrateur de base de données

    Informations forums :
    Inscription : Octobre 2002
    Messages : 80
    Par défaut asynchrone synchrone attente fin de boucle
    Bonjour à tous,
    je m'arrache le peu de cheveux qu'il me reste...
    je veux faire un truc tout bête, qui serrais fini en synchrone depuis longtemps mais en asynchrone j'ai du rater un truc.

    J'ai fait un exemple simple mais qui reflète déjà bien mon problème.

    j'ai une boucle avec un appel externe et à la fin de cette boucle je veux renvoyer le tableau.
    Comme vous pouvez le voir sur ce code tout est renvoyé avant que la boucle finisse

    Help
    j'ai surement du rater un gros truc mais ça alourdi considérablement bien le code le asynchrone, dommage qu'on ne puisse pas activer ou desactiver cette fonctionnalité...

    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
     
    const Request = require("request");
    const pers = ["pascal", "laurent", "marion", "melanie"]
    const pwd = "https://www.passwordrandom.com/query?command=guid&format=json&count=1"
    const tab = { "name": "", "pass": "" }
    var tokenTab = []
     
    function newpass(pe) {
        return new Promise(function (resolve, reject) {
            Request(pwd, function (error, response, body) {
                if (error) {
                    reject(error)
                }
                var pw = JSON.parse(body).char[0]
                resolve(pw)
            })
        })
    }
     
    async function start() {
        console.log("start")
        await step1();
        console.log(tokenTab)
        console.log("end")
     
    }
     
    function step1() {
     
        pers.forEach(el => {
            //console.log(el)
            newpass(el).then(z => {
                //console.log(z)
                var tt = tab
                tt.name = el
                tt.pass = z
                tokenTab.push(tt)
                console.log(tt)
            })
        })
     
    }
     
    start()

  2. #2
    Modérateur

    Avatar de NoSmoking
    Homme Profil pro
    Inscrit en
    Janvier 2011
    Messages
    17 211
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Janvier 2011
    Messages : 17 211
    Par défaut
    Bonjour,
    regarde du côté de l'utilisation de await qui met l’interpréteur « en pause ».

  3. #3
    Membre confirmé
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Octobre 2002
    Messages
    80
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Administrateur de base de données

    Informations forums :
    Inscription : Octobre 2002
    Messages : 80
    Par défaut
    j'ai déjà essayé mais j'y arrive pas ?
    je passe a coté d'un truc...


    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
     
    const Request = require("request");
    const pers = ["pascal", "laurent", "marion", "melanie"]
    const pwd = "https://www.passwordrandom.com/query?command=guid&format=json&count=1"
    const tab = { "name": "", "pass": "" }
    var tokenTab = []
     
     
    function newpass(pe) {
        return new Promise(function (resolve, reject) {
            Request(pwd, function (error, response, body) {
                if (error) {
                    reject(error)
                }
                var pw = JSON.parse(body).char[0]
                resolve(pw)
            })
        })
    }
     
    async function start() {
        console.log("start")
        var tt = await step1();
        console.log("end")
    }
     
    function step1() {
        pers.forEach(async (el) => {
            //console.log(el)
            var ret = await newpass(el)
            console.log(ret)
        })
        console.log("fin de boucle")
    }
     
    start()

  4. #4
    Expert confirmé
    Avatar de Watilin
    Homme Profil pro
    En recherche d'emploi
    Inscrit en
    Juin 2010
    Messages
    3 100
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : En recherche d'emploi

    Informations forums :
    Inscription : Juin 2010
    Messages : 3 100
    Par défaut
    L’idée du await rend le code plus simple à comprendre… En théorie. Le problème c’est la méthode .forEach qui ne « comprend » pas quand on lui passe une fonction async. Tu y arriverais avec une boucle for classique, à condition qu’elle soit elle-même dans une fonction async.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    async function step1() {
     
        for (const el of pers) {
            //console.log(el)
            const z = await newpass(el)
            //console.log(z)
            var tt = tab
            tt.name = el
            tt.pass = z
            tokenTab.push(tt)
            console.log(tt)
        }
     
    }
    Mais il y a un inconvénient à cette façon de faire : on perd le parallélisme des requêtes, car elles sont faites les unes à la suite des autres.

    Une solution plus efficace consiste à :
    1. lancer toutes les requêtes en même temps dans une boucle synchrone qui n’attend pas les résultats ;
    2. utiliser Promise.all() pour renvoyer le tableau quand toutes les requêtes sont terminées.


    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
    function step1() {
     
        const promises = []
     
        pers.forEach(el => {
            //console.log(el)
            promises.push(
                newpass(el).then(z => {
                    //console.log(z)
                    var tt = tab
                    tt.name = el
                    tt.pass = z
                    //tokenTab.push(tt) // tokenTab n’est plus nécessaire
                    console.log(tt)
                })
            )
        })
     
        Promise.all(promises).then((tokens) => {
          console.log(tokens);
        });
     
    }
    La FAQ JavaScript – Les cours JavaScript
    Touche F12 = la console → l’outil indispensable pour développer en JavaScript !

  5. #5
    Membre confirmé
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Octobre 2002
    Messages
    80
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Administrateur de base de données

    Informations forums :
    Inscription : Octobre 2002
    Messages : 80
    Par défaut
    Merci Watilin,
    j'aime mieux l'idée d'envoyer les requêtes en asynchrone et d'attendre la fin de toutes les promesses.

    du coup j'ai fait le script avec ton exemple ça donne ça ...
    mais le resutat est surprenant.
    le log semble ok, mais le log du tableau des promesses ne fait apparaitre que le meme ????

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    { name: 'laurent', pass: '3f43385-0cd5-4eac-b57b-17506096fc49' }
    { name: 'marion', pass: 'd9c3eae-9b2b-4fc4-b6dd-47a9b34c1999' }
    { name: 'melanie', pass: '6e14885-e3c3-44c1-9941-81ee7eba874c' }
    { name: 'pascal', pass: 'eca99a8-0670-44f5-b78e-ae24c7c38885' }
     
    Resultat du tableau Promise.all ???
     
    [ { name: 'pascal', pass: 'eca99a8-0670-44f5-b78e-ae24c7c38885' },
      { name: 'pascal', pass: 'eca99a8-0670-44f5-b78e-ae24c7c38885' },
      { name: 'pascal', pass: 'eca99a8-0670-44f5-b78e-ae24c7c38885' },
      { name: 'pascal', pass: 'eca99a8-0670-44f5-b78e-ae24c7c38885' } ]

    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
    const pers = ["pascal", "laurent", "marion", "melanie"]
    const pwd = "https://www.uuidgenerator.net/api/version4"
    const tab = { "name": "", "pass": "" }
    var rest = require('rest')
     
    async function newpass(per) {
        var pw = await rest(pwd)
        var ret = JSON.parse(JSON.stringify(pw.entity)).substring(1, 36)
        return ret
    }
     
    function step1() {
        const promises = []
        pers.forEach(el => {
            promises.push(
                newpass(el).then(z => {
                    var tt = tab
                    tt.name = el
                    tt.pass = z
                    console.log(tt)
                    return tt
                })
            )
        })
     
        Promise.all(promises).then((tokens) => {
            console.log(tokens);
        });
    }
     
    step1();

  6. #6
    Modérateur

    Avatar de NoSmoking
    Homme Profil pro
    Inscrit en
    Janvier 2011
    Messages
    17 211
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Janvier 2011
    Messages : 17 211
    Par défaut
    tu utilises un « pointer » sur ton objet tab en écrivant tt = tab, donc à chaque tour tu modifies en fait tab.
    Remplace ta ligne :
    par
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    const tt = Object.create(tab)

  7. #7
    Membre confirmé
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Octobre 2002
    Messages
    80
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Administrateur de base de données

    Informations forums :
    Inscription : Octobre 2002
    Messages : 80
    Par défaut
    pouaaaaa je m'aperçois que j'ai des mauvais reflexe d'autres langages.
    milles mercis je vais pouvoir terminer ce morceau... grace à vous tous.

    Merci.

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

Discussions similaires

  1. attente fin backgroundworker
    Par clod83 dans le forum Windows Presentation Foundation
    Réponses: 7
    Dernier message: 14/05/2008, 02h23
  2. [STL] condition fin de boucle avec iterateurs
    Par ZaaN dans le forum SL & STL
    Réponses: 5
    Dernier message: 30/06/2007, 14h52
  3. [C#] Attente fin de thread
    Par ekinox17 dans le forum Windows Forms
    Réponses: 7
    Dernier message: 18/05/2006, 15h52
  4. Appel Asynchrone/Synchrone
    Par Dry dans le forum CORBA
    Réponses: 3
    Dernier message: 26/04/2005, 20h43
  5. Réponses: 6
    Dernier message: 25/03/2002, 21h11

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