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 :

Appel synchrone de callback


Sujet :

JavaScript

  1. #1
    Membre averti
    Inscrit en
    Juin 2006
    Messages
    40
    Détails du profil
    Informations forums :
    Inscription : Juin 2006
    Messages : 40
    Par défaut Appel synchrone de callback
    Bonjour,

    Je suis en train de développer un site web avec une googlemap intégrée ce qui m'oblige malheureusement a me mettre au javascript (API en javascript)...et je ne suis pas forcémnt trés à l'aise avec ce langage.

    Jusqu'a maintenant, je n'avais rencontré aucun problème (enfin presque) mais se pose à moi un problème lié à l'appel de callbacks (apparement exécutés de façon asynchrone)

    En gros, l'application demande à l'utilisateur une adresse de départ, et une adresse d'arrivée. Ensuite, grâce au geocoder fourni par l'API googlemap, je retrouve toutes les possibilitées d'adresses correspondantes à ce qu'il a entré.

    Cela se fait de la facon suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    ok=true;
    geocoder.getLocations(addressDep, function(response) {getPos(response,document.getElementById("choosedep"))});
    geocoder.getLocations(addressArr, function(response) {getPos(response,document.getElementById("choosearr"))});
    if (ok)
    {
    alert("c'est tout bon");
    }
    getLocations() : méthode de l'objet geocoder (GClientGeocoder) qui prend en paramètre une adresse (string) et une fonction de callback
    addressDep et addressArr : les adresses de départ et d'arrivée issues des input
    getPos() : fonction qui est appelée dans le callback et qui modifie la variable ok en fonction de plusieurs paramètre que je ne vais pas exposer ici
    ok : variable booléenne modifiée dans getPos et qui teste si l'adresse entrée existe et si il n'y a qu'une adresse réelle correspondante (pour chaque input)

    Mon problème : le test effectué à l'issu des deux appels n'est pas pertinent car la variable ok n'est pas encore modifiée (execution du callback dans un thread parallèle)

    Ma question : est-il possible de rendre l'execution du callback synchrone ???

    merci

    Lantier!

  2. #2
    Expert confirmé
    Avatar de javatwister
    Homme Profil pro
    danseur
    Inscrit en
    Août 2003
    Messages
    3 684
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Calvados (Basse Normandie)

    Informations professionnelles :
    Activité : danseur

    Informations forums :
    Inscription : Août 2003
    Messages : 3 684
    Par défaut
    demande le statut de ok à la fin de getLocations() et non après les 2 appels de fonctions; si ok passe à true, ce sera le signe que le traitement est terminé et que le test a forcément eu lieu;

  3. #3
    Membre averti
    Inscrit en
    Juin 2006
    Messages
    40
    Détails du profil
    Informations forums :
    Inscription : Juin 2006
    Messages : 40
    Par défaut
    huh ?
    le problème c'est que getLocations ce n'est pas une de mes fonctions mais une méthode fournie par l'API googlemap...donc je peux pas faire mon test dedans...

    et j'ai pas bien compris comment ca règlerai le problème ??
    si ce que tu voulais dire c'était de faire le test à la fin du getPos(), ca ne marche pas puisque ce que je veux c'est qu'a l'issu des deux appels, ok soit a true (ce qui signifierai que les 2 adresses sont correcte et identifiables) et la, la variable est modifiée mais seulement après (puisque c'est fait en parallèle)

    en fait la pluspart du temps, ok passera a false et il faudra refaire une recherche jusqu'a ce qu'elle ne soit plus modifiée.

    n'y a-t-il pas un moyen d'attendre que la variable soit modifiée avant de faire le test ??

  4. #4
    Expert confirmé
    Avatar de javatwister
    Homme Profil pro
    danseur
    Inscrit en
    Août 2003
    Messages
    3 684
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Calvados (Basse Normandie)

    Informations professionnelles :
    Activité : danseur

    Informations forums :
    Inscription : Août 2003
    Messages : 3 684
    Par défaut
    es-tu obligé d'initialiser ok à true, avant le traitement des données?

    du coup, tu fais ton test dans un setInterval;

  5. #5
    Membre averti
    Inscrit en
    Juin 2006
    Messages
    40
    Détails du profil
    Informations forums :
    Inscription : Juin 2006
    Messages : 40
    Par défaut
    ben nan, je ne suis pas obligé, je peux aussi bien l'initialiser a null ou encore ne pas l'initialiser du tout et l'affecter directement dans mon getPos().

    par contre, kesako setInterval pour les tests ??

    sinon, il me reste encore la solution de faire un

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    ok = null
    //appels aux fonctions
    while(ok == null);
    if (ok)
      alert("c'est tout bon !")
    mais la du coup, quand la première aura changé la valeur, ca attendra pas la deuxième...

    alors peut-être :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    oktmp = null;
    //appel a la première fonction
    while(oktmp == null);
    var ok=oktmp;
    oktmp = null;
    //appel a la deuxième fonction
    while(oktmp == null);
    ok &= oktmp;
    if (ok)
      alert("c'est tout bon !");
    ca devrait fonctionner nan ?
    Qu'en pensez-vous ?

  6. #6
    Expert confirmé
    Avatar de javatwister
    Homme Profil pro
    danseur
    Inscrit en
    Août 2003
    Messages
    3 684
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Calvados (Basse Normandie)

    Informations professionnelles :
    Activité : danseur

    Informations forums :
    Inscription : Août 2003
    Messages : 3 684
    Par défaut
    c'est une manière simple de lancer une instruction à intervalle défini, jusqu'à ce qu'une condition soit remplie (sans la paralysie provoquée par while);

    dans ton cas, ça va laisser le temps au traitement de s'accomplir, avant que le test "ok" se réalise;

    bref, c'est pour ça que je te déconseillais de mettre ok à true au début: vu que le test est effectué avant la fin des traitements, tu obtiens forcément une réponse positive!;


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    setInterval("if(ok){alert('ok')}",1)

  7. #7
    Membre averti
    Inscrit en
    Juin 2006
    Messages
    40
    Détails du profil
    Informations forums :
    Inscription : Juin 2006
    Messages : 40
    Par défaut
    ok, je vois comment ca marche mais je ne crois pas que ca puisse régler mon problème parceque je voudrais que ca me redirige sur une autre page si ok est vrai et que l'utilisateur spécifie une autre adresse si ok est faux...

    et donc dans le cas ou c'est faux, la fonction mère (celle où se trouve mes appels et mon test) sera rappelée par l'appui sur un bouton de recherche et donc le setInterval sera lui aussi rappelé...ca pose problème nan ?

    ou alors je fais un:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    setInterval("if(ok){alert('ok');}clearInterval();",1);
    peut-être aussi que je suis a coté de la plaque...

    et 1 milliseconde c'est peut-être un peu court d'autant plus que le temps d'exec va dépendre de la machine client ce qui fait que c'est difficile de savoir combien de temps attendre...

  8. #8
    Expert confirmé
    Avatar de javatwister
    Homme Profil pro
    danseur
    Inscrit en
    Août 2003
    Messages
    3 684
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Calvados (Basse Normandie)

    Informations professionnelles :
    Activité : danseur

    Informations forums :
    Inscription : Août 2003
    Messages : 3 684
    Par défaut
    tu ne peux pas imaginer 2 variables ok et ok2 correspondant aux 2 appels de getPos(), et tester ok_all après, en fonction des résultats?
    disons que si ok_all != false, tu lances ta redirection ou le retour à la saisie;

    pour le "bouton recherche", chaque appui doit réinitialiser les variables;

  9. #9
    Membre averti
    Inscrit en
    Juin 2006
    Messages
    40
    Détails du profil
    Informations forums :
    Inscription : Juin 2006
    Messages : 40
    Par défaut
    hmm...
    genre en mettant un retour dans getPos() ?
    comme ca :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    geocoder.getLocations(addressDep, function(response) {ok1=getPos(response,document.getElementById("choosedep"))});
    geocoder.getLocations(addressArr, function(response) {ok2=getPos(response,document.getElementById("choosearr"))});
    
    setInterval("if(ok1!=null && ok2!=null && ok1 && ok2){alert('ok');}",1);
    ca marcherai un truc pareil ??
    ca règle pas le problème du temps d'attente...et est-ce qu'il faut libérer le setInterval obligatoirement ou bien ?

  10. #10
    Expert confirmé
    Avatar de javatwister
    Homme Profil pro
    danseur
    Inscrit en
    Août 2003
    Messages
    3 684
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Calvados (Basse Normandie)

    Informations professionnelles :
    Activité : danseur

    Informations forums :
    Inscription : Août 2003
    Messages : 3 684
    Par défaut
    le setInterval ne pèse rien et peut tourner 3000 ans s'il s'agit d'évaluer un simple booleen;
    mais de toute façon, la solution la plus sage est de générer l'action voulue (redirection, retour) dans getPos() elle-même;

    un flag indique après le premier passage que addressDep existe et lance le deuxième passage; même principe en fin de 2e passage, et tu n'as plus besoin d'un test exterieur à la fonction;

  11. #11
    Membre averti
    Inscrit en
    Juin 2006
    Messages
    40
    Détails du profil
    Informations forums :
    Inscription : Juin 2006
    Messages : 40
    Par défaut
    je suis désolé mais je comprends pas comment faire ca...
    je te met le code de getPos() :

    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
            function getPos(response, listbox)
            {
                //si on a pu géocoder l'adresse
                if (response && response.Status.code == 200)
                {
                    //si il ya plus d'une réponse
                    if (response.Placemark.length > 1)
                    {
                        listbox.style.display="";
                        clearList(listbox);
                        //je rempli une listbox avec les différents choix
                        for (i=0;i<response.Placemark.length;i++)
                        {
                            var place = response.Placemark[i];
                            listbox.options[listbox.options.length] = new Option(place.address);
                        }
                        listbox.selectedIndex = 0;
                        select_changed(listbox.id, listbox.id.substring(listbox.id.length-3, listbox.id.length));
                        ok = false;
                    }
                    //si il n'y a qu'une adresse correspondante
                    else if (response.Placemark.length == 1)
                    {
                        listbox.style.display="none";
                        document.getElementById(listbox.id.substring(listbox.id.length-3, listbox.id.length)).value=response.Placemark[0].address;
                        ok = true;
                    }
                }
                else
                {
                    alert("sorry, we are unable to geocode this adress in Dublin");
                    ok = false;
                }
            }
    voila...comme getPos est indépendant de l'entrée (départ ou arrivée), je ne vois vraiment pas comment faire pour générer mon action après que les deux soient testée !

    je dois pas être trés bon la...

  12. #12
    Membre averti
    Inscrit en
    Juin 2006
    Messages
    40
    Détails du profil
    Informations forums :
    Inscription : Juin 2006
    Messages : 40
    Par défaut
    bon alors j'ai essayé avec les while et ca fait un peu de la m...de !
    IE me dit qu'un script ralentit l'execution et me demande si je veux l'arrêter...
    Ce n'est donc pas une bonne solution !

    le setInterval ca ne va pas trés bien non plus...ca fait des trucs trés bizarres...

  13. #13
    Expert confirmé
    Avatar de javatwister
    Homme Profil pro
    danseur
    Inscrit en
    Août 2003
    Messages
    3 684
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Calvados (Basse Normandie)

    Informations professionnelles :
    Activité : danseur

    Informations forums :
    Inscription : Août 2003
    Messages : 3 684
    Par défaut
    schématiquement, ce serait ça (dis-moi si ça te parle!)


    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
    <script type="text/javascript">			
     
    var begin, end;
     
    function getPos(response){
     
    	if(toutbaigne){
    		if(!begin){// si "départ" n'est pas encore évalué
    			begin=true
    		}
    		else{// si "départ" a déjà été évalué
    			end=true
    		};
    		alert("données acceptées")
    	}
    	else{
    		begin=false; 
    		end=false;
    		alert("données refusées")
    	}
    }
     
    </script>

  14. #14
    Membre averti
    Inscrit en
    Juin 2006
    Messages
    40
    Détails du profil
    Informations forums :
    Inscription : Juin 2006
    Messages : 40
    Par défaut
    oui, ok mais ca ca ne fonctionne que pour 1 appel nan ??
    ma redirection (par exemple) ne devra se faire qu'après avoir accepté les données de départ ET d'arrivée...

    Alors a quel moment je peux être sur de ca...ou sur du contraire ?

    le if(toutbaigne) ca correspond chez moi au if (response.Placemark.length == 1) ?

    bref, nan ca ne me parle peut-être pas assez... !
    sorry !

  15. #15
    Expert confirmé
    Avatar de javatwister
    Homme Profil pro
    danseur
    Inscrit en
    Août 2003
    Messages
    3 684
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Calvados (Basse Normandie)

    Informations professionnelles :
    Activité : danseur

    Informations forums :
    Inscription : Août 2003
    Messages : 3 684
    Par défaut
    c'est parce que j'ai mal placé l'alert victorieuse

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    if(toutbaigne){
    		if(!begin){// si "départ" n'est pas encore évalué
                               begin=true
    		}
    		else{// si "départ" a déjà été évalué
                               end=true
                               alert("données acceptées")
    		};
    	}

  16. #16
    Membre averti
    Inscrit en
    Juin 2006
    Messages
    40
    Détails du profil
    Informations forums :
    Inscription : Juin 2006
    Messages : 40
    Par défaut
    a si en fait je crois que j'ai compris l'idée mais ca ne marchera que si les deux callbacks s'exécutes dans le même thread...quand on fait deux callbacks, ils sont synchronisés ???

  17. #17
    Expert confirmé
    Avatar de javatwister
    Homme Profil pro
    danseur
    Inscrit en
    Août 2003
    Messages
    3 684
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Calvados (Basse Normandie)

    Informations professionnelles :
    Activité : danseur

    Informations forums :
    Inscription : Août 2003
    Messages : 3 684
    Par défaut
    a priori, les traitements se suivent... mais javascript a un fonctionnement si imprévisible...
    d'où l'idée que j'avais eue d'un appel récursif de getPos(), ce qui signifierait un seul appel de getLocations(); à mon avis, ça résout le problème; mais je ne sais pas si tu peux te le permettre?

  18. #18
    Membre averti
    Inscrit en
    Juin 2006
    Messages
    40
    Détails du profil
    Informations forums :
    Inscription : Juin 2006
    Messages : 40
    Par défaut
    Citation Envoyé par javatwister Voir le message
    a priori, les traitements se suivent... mais javascript a un fonctionnement si imprévisible...
    ca tu l'as dit !

    d'où l'idée que j'avais eue d'un appel récursif de getPos(), ce qui signifierait un seul appel de getLocations(); à mon avis, ça résout le problème; mais je ne sais pas si tu peux te le permettre?
    bah en fait ca parait pas possible, parceque getLocations() prend en paramètre une adresse, et ca n'est pas la même dans les deux cas...sinon, faudrait que je modifie le tout et que le deuxième appel à getLocation() se fasse dans le premier getPos() et donc que je fasse deux fonctions différentes...un getPosDep() et un getPosArr(), ce qui est un peu lourd mais bon...

    je vais tester ta solution et pis si ca fonctionne pas, je changeai tout...tant pis !

    je te tiens au jus !

  19. #19
    Membre averti
    Inscrit en
    Juin 2006
    Messages
    40
    Détails du profil
    Informations forums :
    Inscription : Juin 2006
    Messages : 40
    Par défaut
    j'ai essayé ta technique,ca se passe bien dans la majorité des cas...

    mais quelques fois ca passe dans l'"alerte victorieuse" alors qu'il ne faudrait pas !

    on dirait bien que les 2 callbacks s'exécutent en parallèle...

    chier !

  20. #20
    Expert confirmé
    Avatar de javatwister
    Homme Profil pro
    danseur
    Inscrit en
    Août 2003
    Messages
    3 684
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Calvados (Basse Normandie)

    Informations professionnelles :
    Activité : danseur

    Informations forums :
    Inscription : Août 2003
    Messages : 3 684
    Par défaut
    et avec une 3e variable, incrémentée?


    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
    var begin, end;
     
    var passage=0;
     
     
    function getPos(response){
     
    	if(toutbaigne){
    		passage++;
     
    		if(!begin){// si "départ" n'est pas encore évalué
    			begin=true
    		}
    		else{// si "départ" a déjà été évalué
    			end=true
    		};
     
    		if(passage==2){
            		alert("données acceptées"); action lancée;
    		}
    	}
    	else{
    		passage=0;
    		begin=false; 
    		end=false;
    		alert("données refusées")
    	}
     
    }

Discussions similaires

  1. Remote Procedure Call - Appel Synchrone
    Par gufra dans le forum GWT et Vaadin
    Réponses: 16
    Dernier message: 07/08/2008, 17h23
  2. Appel d'une callback depuis un autre module
    Par Bayard dans le forum Général Python
    Réponses: 6
    Dernier message: 08/06/2008, 17h47
  3. AQ 10G-Exception généré par un PL appelé via un callback
    Par The Machin X dans le forum Administration
    Réponses: 0
    Dernier message: 14/05/2008, 15h11
  4. Réponses: 5
    Dernier message: 06/04/2008, 13h09
  5. Appel d'un callback sur un event un peu particulier
    Par Jim_Nastiq dans le forum Général JavaScript
    Réponses: 5
    Dernier message: 04/06/2007, 16h40

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