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 :

setTimeout avec des références de fonction et paramètres


Sujet :

JavaScript

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre régulier
    Homme Profil pro
    Inscrit en
    Octobre 2013
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations forums :
    Inscription : Octobre 2013
    Messages : 10
    Par défaut setTimeout avec des références de fonction et paramètres
    Bonjour,
    Je veux ajouter une méthode à l'objet Array de JS. Cette méthode trie un tableau, avec un tri par sélection et affiche l'évolution du tri à l'aide de canvas. Le code est le suivant:

    ...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    Array.prototype.echange=function(i,j){
                var t=this[i]
                this[i]=this[j]
                this[j]=t
                return this
    }
    ...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    Array.prototype.visuel=function(ctx,w,h){
                ctx.clearRect(0,0,w,h);
                var qx=w/this.length
                var qy=h/this.max()          
                for (var i=0; i<this.length; i++) {
                    ctx.beginPath()
                    ctx.arc(qx/2+i*qx,qy/2+ this[i]*qy,1,0,2*Math.PI,true)
                    ctx.stroke()
                }          
            }
    ...

    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
     
    Array.prototype.triVisuel=function(ctx,w,h){
                var aux=this
                aux.visuel(ctx,w,h)
                var c=1
                for (var i=0; i<aux.length-1; i++) {
                    for (var j=i+1; j<aux.length; j++) {
                        var min=i
                        if (aux[j]<aux[min]) {
                            min=j
                        }
                        aux=aux.echange(i,min)
                        setTimeout(function(){return function(aux){aux.visuel(ctx,w,h)};},100*c);
                        c++
                    }
                }
            }
    Toutes mes méthodes fonctionnent sauf la dernière... Il y a un problème avec setTimeout ... et après des heures de recherche, je ne trouve toujours pas ...
    Merci pour votre aide,

  2. #2
    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
    Par défaut
    C'est le bug classique. setTimeout fait un appel asynchrone, donc quand la fonction passée est exécutée, ta variable itérateur a déjà fini son tour de boucle.
    La technique consiste donc à utiliser une closure, c'est à dire une sous-fonction qui sera unique pour chaque tour de boucle. On passe le ou les arguments voulus à cette sous-fonction pour s'assurer qu'ils ne changeront pas au prochain tour de boucle.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    setTimeout( (function(){
       return function(aux){
           aux.visuel(ctx,w,h)
        };
    }) (aux)
    ,100*c);
    En gros c'est une fonction qui crée une autre fonction. Ta variable aux se retrouve copiée en tant qu'argument, et tu utilises la copie dans ta sous-fonction.

  3. #3
    Membre régulier
    Homme Profil pro
    Inscrit en
    Octobre 2013
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations forums :
    Inscription : Octobre 2013
    Messages : 10
    Par défaut
    Merci SylvainPV pour tes explications. J'ai modifié la syntaxe mais le problème reste toujours. En affichant la variable aux dans une alerte, je remarque que le tri s'effectue normalement. Malgré tout la mise à jour de la partie canvas ne s'effectue toujours pas!

    Je t'envoie ma méthode de tri modifié ainsi ainsi que ma fonction charger() qui se lance au chargement de la page. C'est depuis cette fonction que j'effectue mes tests, sans succès hélas!
    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
     
              Array.prototype.triVisuel2=function(ctx,w,h){
                var aux=this
                aux.visuel(ctx,w,h)
                var c=1
                for (var i=0; i<aux.length-1; i++) {
                    for (var j=i+1; j<aux.length; j++) {
                        var min=i
                        if (aux[j]<aux[min]) {
                            min=j
                        }
                        aux=aux.echange(i,min)
                        //alert(aux)
                        setTimeout( (function(){
                            return function(aux){
                                aux.visuel(ctx,w,h)
                            };
                        }) (aux)
                        ,100*c);
                        c++
                    }
                }
            }
     
     
            // Tests des nouvelles méthodes
     
            function $(id){return document.getElementById(id)}
            function charger(){
                var x=[20,40,12,27,12,23]
                var y=[]
                var ctx=$('canvas').getContext('2d')
                //y.alea(6,0,50)
                x.triVisuel2(ctx,$("canvas").width,$("canvas").height)
            }

  4. #4
    Membre régulier
    Homme Profil pro
    Inscrit en
    Octobre 2013
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations forums :
    Inscription : Octobre 2013
    Messages : 10
    Par défaut
    Après de nouvelles recherches, j'ai essayer deux nouvelles idées
    l'idée A est très proche de l'idée à SylvainPV, un succès faible, on voit uniquement le tableau au début et le tableau à la fin.
    l'idée B, après un peu de recherche sur le net

    ... Rien ne se passe,... je ne sais vraiment pas comment faire...

    Voici les codes...
    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
     
     
           Array.prototype.triVisuel2=function(ctx,w,h){
                var aux=this
                aux.visuel(ctx,w,h)
                var c=1
                var mesTab=[]
                for (var i=0; i<aux.length-1; i++) {
                    for (var j=i+1; j<aux.length; j++) {
                        var min=i
                        if (aux[j]<aux[min]) {
                            min=j
                        }
                        aux=aux.echange(i,min)
                        mesTab.push(aux.visuel) // pour idée 2...
                        //alert(aux) début idée 1 ne fonctionne pas bien!!
                        /*setTimeout( (function(aux){
                            return function(){
                                aux.visuel(ctx,w,h)
                               };
                        }) (aux)
                       ,500);
                        c++*/
                        // fin idée 1
                    }
                }
                // idée 2 ne fonctionne vraiment pas !
                for(var i=0;i<mesTab.length;i++){
                    setTimeout(
                        (function(arg){
                            return function(){
                                mesTab[arg](ctx,w,h);
                            };
                        })(i),100
                    );
                }
            }
    Si qqn a une idée, c'est volontiers! Merci à vous.

  5. #5
    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
    Par défaut
    On ne sait pas ce que tu cherches à faire, donc difficile de t'aider.

    Tu as plusieurs fonctions dans ton code. Peux-tu tester individuellement les entrées/sorties ? Ca nous donnera au moins une idée de où chercher.

  6. #6
    Modérateur

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

    Informations forums :
    Inscription : Janvier 2011
    Messages : 17 207
    Par défaut
    Bonjour,
    si tu cherches à faire du progressif il ne te faut pas lancer toutes tes fonctions en même temps.
    exemple :
    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
    <!DOCTYPE html>
    <html lang="fr">
    <head>
    <meta charset="UTF-8">
    <title>setTimeout différé</title>
    </head>
    <body>
    <div id="result"></div>
    <script>
    var mesTab  = 'Bonjour vous !!'.split('');
    var oDiv = document.getElementById('result');
    for(var i = 0; i < mesTab.length; i++){
      (function( txt, delai){
        setTimeout( function(){
            oDiv.innerHTML += txt;
          }, delai);
      })(mesTab[i], 100*i);
    }
    </script>
    </body>
    </html>

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

Discussions similaires

  1. Remplissage d'une feuille avec des références similaires.
    Par Potzo dans le forum Macros et VBA Excel
    Réponses: 4
    Dernier message: 23/06/2010, 10h51
  2. Créer une fiche avec des procédures et fonctions
    Par ibrahim26 dans le forum ASP.NET
    Réponses: 1
    Dernier message: 16/12/2008, 01h54
  3. remplir un tableau avec des références à plusieurs feuilles
    Par Amiral19 dans le forum Macros et VBA Excel
    Réponses: 10
    Dernier message: 22/07/2007, 22h26
  4. Réponses: 1
    Dernier message: 09/05/2007, 10h57
  5. Utilisation de setTimeout avec des classes : BUG!
    Par seb-oulba dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 01/09/2006, 09h43

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