2010-12-02 35 views
0
this.plotted = [jQuery('#img1'), jQuery('#img2'), jQuery('#img3')]; 

Blah.prototype.animate = function() 
{ 
    if (!this.plotted.length) 
     throw 'Blah::animate - No points have been plotted'; 

    // fix the scope 
    var _this = this; 

    var animateOn = function(image) 
    { 
     image.attr('src', _this.options.pointActive); 

     setTimeout(function() { animateOff(point); }, 700); 
    } 

    var animateOff = function(image) 
    { 
     image.attr('src', _this.options.pointDefault); 

     setTimeout(function() { animateOn(point); }, 700); 
    } 

    for (var i = 0; i < this.plotted.length; i++) 
    { 
     var point = this.plotted[i]; 

     setTimeout(function() { animateOn(point); }, 700); 
    } 
} 

J'essaye d'animer ces 3 images en commutant leurs src entre une 'sur' et une 'hors' image. Je ne veux pas que cela soit "séquentiel". Par exemple, je ne veux pas voir le premier changement d'image, puis le deuxième puis le troisième. J'utilise setTimeout pour accomplir ceci. Eh bien, j'essaie de ...Avoir quelques problèmes avec mon Javascript non-bloquant

Tout d'abord, le problème que j'ai est avec le setTimeout à l'intérieur du for loop.

for (var i = 0; i < this.plotted.length; i++) 
{ 
    var point = this.plotted[i]; 

    console.log(point); // this correctly shows each image point 

    setTimeout(function() 
    { 
     console.log(point); // this shows the same, first, point 
     animateOn(point); 
    }, 700); 
} 

Je ne sais pas ce que le point intérieur ne correspond pas à l'extérieur point:/

Aussi, je voudrais savoir si cette méthode est, bien, stupide. Est-ce que ces appels de fonction imbriqués vont continuellement se construire sur la pile et finiront par me manquer de RAM? Y a-t-il une meilleure façon d'aborder cela?

Répondre

0

Cela ne fonctionne pas en raison du fonctionnement des fermetures.

Je ferais comme ça:

var makeAnimateStarter = function(point) { 
    return function() { 
    animateOn(point); 
    }; 
}; 

for (var i = 0; i < this.plotted.length; i++) 
{ 
    var point = this.plotted[i]; 

    setTimeout(makeAnimateStarter(point), 700); 
} 

Et ce n'est pas un problème d'un point de vue de la pile. Chaque fois qu'un délai d'attente est exécuté, il se trouve dans une nouvelle pile d'appels. C'est pourquoi vous avez besoin de _this. setTimeout() ne suspend pas le thread à ce moment-là, puis reprend l'exécution de la fonction fraîche.