Возникли некоторые проблемы с моим неблокирующим Javascript - PullRequest
0 голосов
/ 02 декабря 2010
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);
    }
}

Я пытаюсь анимировать эти 3 изображения, переключая их src между включенным и выключенным изображением.Я не хочу, чтобы это было «последовательным».То есть я не хочу видеть, как меняется первое изображение, затем второе, а затем третье.

Я использую setTimeout для достижения этой цели.Ну, я пытаюсь ...

Во-первых, у меня проблема с setTimeout внутри 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);
}

Понятия не имею, чтовнутренний point не соответствует внешнему point: /

Кроме того, я хотел бы знать, глуп ли этот метод.Будут ли эти вызовы вложенных функций постоянно накапливаться в стеке и, в конечном итоге, приводить к нехватке памяти?Есть ли лучший способ приблизиться к этому?

1 Ответ

0 голосов
/ 02 декабря 2010

Это не работает из-за того, как работают замыкания.

Я бы сделал это так:

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);
}

И это не проблема с точки зрения стека. Каждый раз, когда выполняется таймаут, он попадает в новый стек вызовов. Вот почему вам требуется _this. setTimeout() не приостанавливает поток в этой точке, а затем возобновляет выполнение функции заново.

...