2014-11-25 1 views
0

Мой вопрос связан со следующим:JavaScript - 'это' внутри SetTimeout и requestAnimationFrame

setTimeout() inside JavaScript Class using “this”

calling a function inside setTimeout and inside a function

Я пытаюсь реализовать простой цикл анимации. Функция draw является функцией-членом объекта состояния. У меня возникают проблемы с тем, чтобы «это» работать в рамках setTimeout и requestAnimationFrame.

У меня есть следующий код:

ANIM.State.prototype = { 
    constructor: ANIM.State, 
    play: function(){ 
     if(!this.paused){ 
      var that = this; 
      setTimeout(function(){ 
       requestAnimationFrame(that.play); 
       that.setFrameNum(that.currentFrame + 1); //draw code is in here 
      }, 1000/24); 
     } 
    } 
}; 

Однако, когда я называю игру(), она работает в два раза и останавливается.

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

ответ

2

Вы можете решить проблему с .bind(), как это:

requestAnimationFrame(that.play.bind(that)); 

Проблема в том, все, что передается requestAnimationFrame() является ссылкой на метод .play и затем выполняется как обычный вызов функции так this внутри это будет неправильно и не укажет на ваш объект. Это обычная проблема при передаче метода в качестве обратного вызова, когда вы хотите, чтобы он был вызван как obj.method().

Существует множество возможных обходов, но самым простым в современных браузерах является использование .bind(), как я показал выше. Это фактически создает небольшую функцию заглушки, которая затем вызывает that.play(), а не только play(), так что ссылка на объект используется по мере необходимости, и это функция заглушки, которая передается в requestAnimationFrame().

Вы также можете сделать это следующим образом (создавая собственную функцию заглушки), хотя .bind() кажется чище мне:

requestAnimationFrame(function() { 
    that.play(); 
});