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

  1. #1
    Futur Membre du Club
    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
    Points : 5
    Points
    5
    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
    Points : 9 943
    Points
    9 943
    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
    Futur Membre du Club
    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
    Points : 5
    Points
    5
    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
    Futur Membre du Club
    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
    Points : 5
    Points
    5
    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
    Points : 9 943
    Points
    9 943
    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 184
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Janvier 2011
    Messages : 17 184
    Points : 44 841
    Points
    44 841
    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>

  7. #7
    Futur Membre du Club
    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
    Points : 5
    Points
    5
    Par défaut
    Merci NoSmoking pour ton exemple, c'est effectivement du progressif que je cherche à faire! (qqch comme l'animation ici http://fr.wikipedia.org/wiki/Tri_par_insertion avec un tri par selection...)

    Je CROIS avoir compris ton exemple et j'ai voulu l'appliquer à mon problème.
    J’obtiens le code suivant:
    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
     
                   Array.prototype.triVisuel2=function(ctx,w,h){
                var aux=this
                aux.visuel(ctx,w,h)
                var mesTab=[],t,c=0
                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)
                        alert(mesTab[c]) //Alert1
                        c++
                    }
                }
                alert(mesTab) //Alert 2
                for(var i = 0; i < mesTab.length; i++){
                        (function( a, delai,ctx,w,h){
                            setTimeout( function(){
                            a.visuel(ctx,w,h);
                        }, delai);
                    })(mesTab[i], 500*i,ctx,w,h);
                    }
            }
    Ici l'animation ne se fait pas et j'avoue ne pas comprendre...
    J'ai ajouté des méthodes à Array:
    tab.visuel(ctx,width,height)// efface le canvas et dessine le tableau dans le canvas.
    tab.echange(i,j) // échange deux cellules du tableau et retourne le tableau modifié [1,2,3].echange(1,2) retourne [1,3,2]
    tab.triVisuel2(ctx,w,h) doit effectuer l'animation dans le canvas.

    L'exemple de NoSmoking illustre exactement ce que je veux faire.(encore merci!) et la partie que j'ai modifié maintenant me semble okay. Par contre, je crois avoir trouvé la faille sans savoir comment y remédier. Je m'explique.

    Une partie de mon problème doit se trouver entre l'alert 1 et l'alert 2. J'ai pris un exemple, le tableau x=[20,40,12,1].
    J'ai lancé l'animation et l'alert 1 affiche
    [20,40,12,1], [20,40,12,1],[1,40,20,12],[1,20,40,12],[1,12,40,20],[1,12,20,40].
    Dans ma tête, mesTab a la forme suivante:
    [[20,40,12,1], [20,40,12,1],[1,40,20,12],[1,20,40,12],[1,12,40,20],[1,12,20,40]]
    et surprise (enfin pour moi!) dans l'alert 2, il a la tête suivante:
    [[1,12,20,40], [1,12,20,40],[1,12,20,40],[1,12,20,40],[1,12,20,40],[1,12,20,40]].

    Dans ce cas, je comprends pourquoi ça ne marche pas mais je ne comprends pas pourquoi dans mon alert 2, c'est pas comme je pensais ...

    Merci pour vos lumières...

  8. #8
    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 943
    Points
    9 943
    Par défaut
    Humm ça ne doit pas être tout à fait la même chose que l'exemple de Wikipedia, sinon je ne vois pas à quoi sert la variable mesTabs et je ne comprends pas l'algorithmique de tri.

    Si on revenait à la première version de triVisuel, parce que là ça part un peu dans tous les sens. En simplifiant et en modifiant la closure, j'arrive à ça:

    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
    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++) {			
    			if (aux[j]<aux[i]) {
    				aux.echange(i,j);
    			}			
    			(function(aux,c){
    				setTimeout(function(){
    					aux.visuel(ctx,w,h);
    				}, 100*c);
    			})(aux,c);
    			c++;
    		}
    	}
    }
    Plutôt que des alert, utilise le debugger intégré à ton navigateur (F12 sur Chrome ou l'extension Firebug sur Firefox).

  9. #9
    Futur Membre du Club
    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
    Points : 5
    Points
    5
    Par défaut
    Merci SylvainPV pour l'énergie que tu passes sur mon code. C'est vraiment sympa!
    Ta solution fonctionne comme la dernière que j'ai posté. J'ai le graphe initiale puis après un délai le tableau trié... Mais je n'ai pas la progression du tri comme sur wiki! Je pense bien que la progression doit être différente, c'est pas la même méthode de tri, mais bon là, il n'y a pas de progresssion...
    Je poste le code complet si tu veux tester...

    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
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
     
    <!DOCTYPE html>
     
    <html>
    <head>
        <title>Tableaux</title>
        <script>
     
            // Ajout de  méthodes à l'objet Array
     
            Array.prototype.supprime=function(ind) {
                for(var i=0;i<this.length-1;i++){
                    if(i>=ind){
                        this[i]=this[i+1]
                    }
                }
                this.length--
                return this
            }
            Array.prototype.echange=function(i,j){
                var t=this[i]
                this[i]=this[j]
                this[j]=t
                return this
            }
            Array.prototype.alea=function(taille,min,max){
                for (var i=0; i<taille; i++) {
                        this[i]=min+Math.floor(Math.random()*(max-min+1))
                    }
                return this
            }
            Array.prototype.max=function(){
                var max=this[0]
                for (var i=0; i<this.length; i++) {
                        if(this[i]>max){max=this[i]}
                    }
                return max
            }
            Array.prototype.triSelection=function(){
                var aux=this
                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)
                    }
                }
                return aux
            }
            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()
                }
     
            }
     
            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++) {			
    			if (aux[j]<aux[i]) {
    				aux.echange(i,j);
    			}
                            //alert(aux)
    			(function(aux,delai){
    				setTimeout(function(){
    					aux.visuel(ctx,w,h);
    				}, delai);
    			})(aux,1000*c);
    			c++;
    		}
                }
            }
     
     
     
            // Tests des nouvelles méthodes
     
            function $(id){return document.getElementById(id)}
            function charger(){
                var x=[20,40,12,1]
                var y=[]
                var ctx=$('canvas').getContext('2d')
                //y.alea(50,0,50)
                x.triVisuel2(ctx,$("canvas").width,$("canvas").height) 
            }
     
        </script>
    </head>   
     
    <body onload="charger()">
        <canvas id="canvas" width="500" height="500" style="border: medium solid rgb(255,0,0)"></canvas>
        </body>
    </html>

  10. #10
    Futur Membre du Club
    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
    Points : 5
    Points
    5
    Par défaut
    J'ai encore modifié le dernier programme en enlevant le graphisme et en affichant à la place une chaine de caractère décrivant l'évolution du tableau.
    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
     
        Array.prototype.triVisuel3=function(uneDiv){
                var aux=this;
                var txt=aux+"</br>"
                var c=1;
                for (var i=0; i<aux.length-1; i++) {
    		for (var j=i+1; j<aux.length; j++) {			
    			if (aux[j]<aux[i]) {
    			    aux.echange(i,j);
                                txt=aux+"</br>"  
    			}
    			(function(aux,delai){
    			    setTimeout(function(){
                                    document.getElementById(uneDiv).innerHTML+=txt;
    			    }, delai);
    			})(aux,100*c);
                            c++;
    		}
                }
            }
    en faisant [20,40,12,1].triVisuel3('test'),
    j'obtient

    1,12,20,40
    1,12,20,40
    1,12,20,40
    1,12,20,40
    1,12,20,40
    1,12,20,40

    ???? -> Toujours le même problème.

    En cherchant sur le net je me suis demandé si je dois utiliser la méthode call. Je ne connais pas vraiment cette méthode mais j'ai l'impression que comme je suis dans un prototype il y a qqch de spécial qui m'échappe.

  11. #11
    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 943
    Points
    9 943
    Par défaut
    Ah bien sûr, je n'avais pas réfléchi au fait qu'on est dans le contexte d'une seule Array. Donc même si tu la passes dans une closure, ça reste le même objet.

    Il faut clôner l'Array et passer le clône à la closure, comme ça on est sûrs de pas modifier le même objet. La manière la plus simple de clôner une Array, c'est d'appeler la méthode slice() sans argument :

    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
      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++) {			
    			if (aux[j]<aux[i]) {
    				aux.echange(i,j);
    			}
    			(function(aux,c){
    				setTimeout(function(){
    					aux.visuel(ctx,w,h);
    				}, 1000*c);
    			})(aux.slice(),c);
    			c++;
    		}
    	}
    };
    et le tour est joué

  12. #12
    Modérateur

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

    Informations forums :
    Inscription : Janvier 2011
    Messages : 17 184
    Points : 44 841
    Points
    44 841
    Par défaut
    @petit-lapin :
    Dans ton exemple,
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    (function(aux,delai){
        setTimeout(function(){
            document.getElementById(uneDiv).innerHTML+=txt;
        }, delai);
    })(aux,100*c);
    attention txt n'est pas passé en paramètre donc au moment de l’exécution txt à la valeur qu'elle aurait en fin de boucle.

    Nota : il te faudrait regarder également du coté de la méthode window.requestAnimationFrame() pour mettre en lieu et place de setTimeout même si ce dernier est reconnu même par les vieux browsers.(ceci n'est pas une priorité néanmoins)

  13. #13
    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 943
    Points
    9 943
    Par défaut
    requestAnimationFrame n'est pas approprié pour ce cas, NoSmoking. Pas besoin de vouloir fluidifier une animation si l'animation affiche une image par seconde.

  14. #14
    Futur Membre du Club
    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
    Points : 5
    Points
    5
    Par défaut
    Magnifique, merci beaucoup pour tous vos efforts !!
    je ne suis pas certain de comprendre pourquoi on peut pas modifier le même objet et pourquoi le clône doit être fait ! Mais ça marche, je n'aurais pas trouvé sans vous! Merci beaucoup pour votre aide.

  15. #15
    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 943
    Points
    9 943
    Par défaut
    On peut modifier le même objet, seulement ce n'est pas ce que tu veux. Toi, tu voulais sauvegarder l'Array dans ses états intermédiaires de tri, puis les afficher un à un avec un délai. C'est pour ça qu'on a voulu utiliser une closure, pour stocker l'état intermédiaire dans le scope interne de la closure (mots compliqués désolé ^^). Seulement la variable sauvegardée en question est une référence (à this en l'occurence). Donc lorsqu'on modifie l'Array, la variable aux dans la closure fait référence à cette Array modifiée. Ce qui explique que quand tu veux l'utiliser à t+1s, t+2s etc. , le tri est déjà fini et tu récupéres la valeur finale.

    Une autre solution que le slice() aurait été de trier l'Array avec les mêmes délais que l'affichage, autrement dit une étape de tri toutes les secondes. Concrètement ça aurait voulu dire mettre la fonction echange à l'intérieur du timeout. Mais l'avantage avec ton code actuel est que tu peux récupérer l'Array triée instantanément.

  16. #16
    Modérateur

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

    Informations forums :
    Inscription : Janvier 2011
    Messages : 17 184
    Points : 44 841
    Points
    44 841
    Par défaut
    Citation Envoyé par SylvainPV
    requestAnimationFrame n'est pas approprié pour ce cas, NoSmoking.
    d'accord avec toi, d'où l'objet de
    Citation Envoyé par NoSmoking
    (ceci n'est pas une priorité néanmoins)
    Toi, tu voulais sauvegarder l'Array dans ses états intermédiaires de tri, puis les afficher un à un avec un délai.
    j'ai eu une approche identique lors de la réalisation du défi 2012 pour la présentation du tri à bulle.
    http://javascript.developpez.com/def...tri_bulle.html

  17. #17
    Futur Membre du Club
    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
    Points : 5
    Points
    5
    Par défaut
    Merci NoSmoking et SylvainPV pour vos explications, je vais faire encore quelques essais ! Merci aussi pour le lien sur le tri à bulle de NoSmoking, c'est vraiment sympa ...

+ 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, 11h51
  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, 02h54
  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, 23h26
  4. Réponses: 1
    Dernier message: 09/05/2007, 11h57
  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, 10h43

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