Partage
  • Partager sur Facebook
  • Partager sur Twitter

Fonction javascript synchrone

Exécuter des fonctions javascript dans un ordre précis

    25 octobre 2016 à 15:47:25

    Bonjour la communauté,

    j'ai un code très simple mais qui ne fonctionne pas à cause de la gestion asynchrone de javascript:

    <!DOCTYPE html>
    <html>
    <head>
      <title>test</title>
      <script>  
    	function main(callback){
    		document.getElementsByTagName('body')[0].style.cursor = 'wait';
    		callback();
    	};
    	
    	function callback(){
    	    var t = 50000;
    		for (var i = 0; i < t; i++) {
    			document.getElementById("myTable").insertRow(0).insertCell(0).innerHTML = i;
    		}
    		document.getElementsByTagName('body')[0].style.cursor = 'auto';	
    	}
      </script>
    </head>
    
    <body>
    <a onclick="main(callback)" style="cursor:pointer;">GO</a>
    <table id="myTable">
      <tr>
        <td>ma premiere</td>
      </tr>
    </table>
    
    </body>
    </html>

    Vous l'aurez compris je souhaite faire apparaître la moulinette du curseur en 'wait' en attendant la fin de ma fonction 'callback'.

    Malheureusement, vous pourrez par simple ctrl-c ctrl-v que le curseur n’apparaît pas.

    Pourriez-vous m'expliquer où est mon erreur?

    • Partager sur Facebook
    • Partager sur Twitter
    Si vous ne réussissez pas du premier coup, appelez ça « version 1.0 ».
      25 octobre 2016 à 16:06:10

      Bonjour,

      Essai de ne garder que la dernière ligne dans ton call back et de remonter le reste dans main().

      • Partager sur Facebook
      • Partager sur Twitter
      Un petit +1 si je vous ai aidé est toujours appréciable :).
        27 octobre 2016 à 8:53:37

        Krogoth:

        J'ai testé avec ce code:

          <script>  
        	function main(callback){
        		document.getElementsByTagName('body')[0].style.cursor = 'wait';
        			    var t = 50000;
        		for (var i = 0; i < t; i++) {
        			document.getElementById("myTable").insertRow(0).insertCell(0).innerHTML = i;
        		}
        		callback();
        	};
        	
        	function callback(){
        		document.getElementsByTagName('body')[0].style.cursor = 'auto';	
        	}
          </script>

        Mais j'ai le même résultat :(

        • Partager sur Facebook
        • Partager sur Twitter
        Si vous ne réussissez pas du premier coup, appelez ça « version 1.0 ».
          27 octobre 2016 à 10:19:24

          Attention, le curseurr imposé sur l'ancre peut masquer celui de la page ! Et puis, ne mélangeons pas les genres avec une fonction non testée isolement.

          <!DOCTYPE html>
          <html>
          <head>
          <title>Tests</title>
          <meta charset="utf-8" />
          <style>
          body {font-family:Garamond}
          a {cursor:pointer}
          </style>
          </head>
          <body>
          <a id="clc" onclick="main(callback)">GO</a>
          
          <script>
           function main(callback){
                  document.body.style.cursor = 'wait';
                  document.getElementById('clc').style.cursor='wait';
                  setTimeout(callback,5000);
              };
          
              function callback(){
                   document.body.style.cursor = 'auto';
                   document.getElementById('clc').style.cursor='auto';
              }
          </script>
          </body>
          </html>

          Ceci fonctionne, la condition à observer consiste à interrompre le script pour que les modifications de la page soient opérées avant le lancement de la fonction. Une brève interruption obtenue par un setTimeout suffirait pour lancer une fonction plus complexe.

          -
          Edité par 007julien 27 octobre 2016 à 10:20:37

          • Partager sur Facebook
          • Partager sur Twitter
            27 octobre 2016 à 10:24:17

            C'est pas très beau mais je préfère quand même ca à la solution du timeout:

            function main(callback) {
                document.getElementsByTagName('body')[0].style.cursor = 'wait';
                var t = 50000;
                for (var i = 0; i < t; i++) {
                    document.getElementById("myTable").insertRow(0).insertCell(0).innerHTML = i;
                    if (i >= t - 1) {
                        callback();
                    }
                }
            };
            
            function callback() {
                document.getElementsByTagName('body')[0].style.cursor = 'auto';
            }

            Avec les promises ca donne quoi? pareil?

            var main = new Promise(
                function(resolve, reject) {
                    document.getElementsByTagName('body')[0].style.cursor = 'wait';
                    var t = 50000;
                    for (var i = 0; i < t; i++) {
                        document.getElementById("myTable").insertRow(0).insertCell(0).innerHTML = i;
                    }
                    resolve(1);
                });
            
            main.then(function() {
            document.getElementsByTagName('body')[0].style.cursor = 'auto';
            }).catch(
                // Promesse rejetée
                function() {
                    console.log("Qu'est ce t'a foutu!!");
                });




            -
            Edité par Krogoth 27 octobre 2016 à 10:30:17

            • Partager sur Facebook
            • Partager sur Twitter
            Un petit +1 si je vous ai aidé est toujours appréciable :).
              27 octobre 2016 à 14:29:36

              007julien: effectivement j'avais trouvé la solution du timeout qui est une solution de contournement, mais qui n'est pas efficace car si le temps d’exécution de ma fonction est de moins de 5 secondes je  bloque l'utilisateur pour rien :(

              Krogoth: je dois me former sur les promises mais j'ai déja trouvé que ça ne fonctionne sur IE que depuis EDGE donc pas compatible avec ma demande :( IE9 en l’occurrence.

              • Partager sur Facebook
              • Partager sur Twitter
              Si vous ne réussissez pas du premier coup, appelez ça « version 1.0 ».
                27 octobre 2016 à 15:47:28

                Tu peux essayer les promises jquery eventuellement. Même si c'est dommage d'utliser jquery que pour ca.
                • Partager sur Facebook
                • Partager sur Twitter
                Un petit +1 si je vous ai aidé est toujours appréciable :).
                  27 octobre 2016 à 22:23:13

                  Il suffit d'un setTimeout de 5 ou 7 millisecondes pour interrompre le script (*), l'utilisateur qui réagit au mieux en 200-250 millisecondes (voir cette page) n'y verra rien !

                  (*) Ce temps est sans rapport avec mon setTimeout qui assure à la fois l'interruption du script et la simulation de l'exécution de la fonction.

                  Autrement dit le schéma serait le suivant :

                  • Clic => script de modification du curseur,
                  • setTimeout d'interruption très court (5 à 7 millisecondes) pour que le script prenne effet
                  • Exécution de la fonction
                  • rétablissement du curseur lancer à la fin de l'exécution pour rétablir le curseur.

                  À titre de démonstration la page suivante fonctionne sur le même principe d'utilisation d'un settimeout pour permettre des sorties intermédiaires.

                  -
                  Edité par 007julien 27 octobre 2016 à 22:35:55

                  • Partager sur Facebook
                  • Partager sur Twitter

                  Fonction javascript synchrone

                  × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                  × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                  • Editeur
                  • Markdown