02.01.2011, 23:07
|
Аспирант
|
|
Регистрация: 02.01.2011
Сообщений: 56
|
|
jQuery, функция animate(), рекурсия
Здравствуйте!
Есть некая игра (что-то наподобе шахмат), для которой на jQuery пишу "плейер". Плейер предназначен для того, чтобы показывать "запись" игры. Игра на двух человек, сначала ходит фигура одного игрока, потом другого, и т.д. Плейеру скармливаются все ходы в игре, он в соответствие с этими ходами перемещает фигуры на экране.
Перемещение фигур должно поисходить так: движется одна фигура, когда она закончила движение, должна перемещаться следующая, и т.д.
В jQuery есть функция animate(), в последнем параметре которой можно указать "конечную" функцию, которая вызывается в конце движения фигуры. Я могу указывать в качестве конечной функции метод начала обработки нового шага, next_step() например.
Но, у меня складывается впечатление, что это создаст рекурсию. Так как в next_step() снова будет вызвана animate() для следующей фигуры, и т.д. Помню, что совсем недавно в браузерах были какие-то ограничения на глубину стека вызовов. То ли 64, толи 100. А в моей игре возможно и 500 ходов и более.
Всвязи с вышеизложенным, вопросы:
1. Действительно ли в вышеописанном случае будет рекурсия?
2. Какие ограничения в JavaScript на стек вызовов в современных браузерах?
3. Как организовать плейер так, чтобы небыло рекурсии? У меня есть предположение сделать машину состояний, и в качестве конечной функции для animate() указать метод, переключащий некий флаг в состояние "ход закончен". Но тогда надо организовывать основной цикл, который будет отслеживать флаги, а его можно организовать только через setTimeout(), что даже при обработке 10 раз в секунду может дать большую нагрузку на браузер.
То есть, мне бы хотелось просто вызывать обработку следующего хода в момент, когда движение фигуры на текущем ходе закончено. Как это сделать?
|
|
02.01.2011, 23:18
|
|
⊞ Развернуть
|
|
Регистрация: 11.01.2010
Сообщений: 1,810
|
|
Сообщение от xintrea
|
1. Действительно ли в вышеописанном случае будет рекурсия?
|
Возьмите и посмотрите. Код jQuery открыт (hint: jQuery.fx.prototype.step, функция будет лежать в this.options.complete).
Рекурсия здесь даже если и есть, то по всей логике она должна быть хвостовой. Не говоря уже о том, что callback будет вызван в другой момент времени (setTimeout / setInterval постарается), когда функция, начавшая анимацию, будет уже давным-давно выполнена.
Последний раз редактировалось B@rmaley.e><e, 02.01.2011 в 23:23.
|
|
02.01.2011, 23:21
|
Аспирант
|
|
Регистрация: 02.01.2011
Сообщений: 56
|
|
> Возьмите и посмотрите. Код jQuery открыт.
Можно было и не отвечать, коль вы не знаете ответа.
|
|
02.01.2011, 23:39
|
|
|
|
Регистрация: 27.12.2008
Сообщений: 4,201
|
|
Сообщение от xintrea
|
Можно было и не отвечать, коль вы не знаете ответа.
|
прочитай ответ еще раз...
Сообщение от xintrea
|
Но, у меня складывается впечатление, что это создаст рекурсию.
|
паранойя?
Последний раз редактировалось x-yuri, 02.01.2011 в 23:42.
|
|
02.01.2011, 23:57
|
Аспирант
|
|
Регистрация: 02.01.2011
Сообщений: 56
|
|
Сообщение от B@rmaley.e><e
|
Возьмите и посмотрите. Код jQuery открыт (hint: jQuery.fx.prototype.step, функция будет лежать в this.options.complete).
Рекурсия здесь даже если и есть, то по всей логике она должна быть хвостовой. Не говоря уже о том, что callback будет вызван в другой момент времени (setTimeout / setInterval постарается), когда функция, начавшая анимацию, будет уже давным-давно выполнена.
|
Насколько я понял, весь jQuery работает на основе очереди, и для каждого обрабатываемого селектора создается очередь. В очередь помещаются "команды", что нужно делать в данный момент времени и информация, на каком этапе находится выполнение "команды". Как только "команда" выполнена, она удаляется из очереди, и начинается выполнение следущей "команды".
Получается, что если вызов "конечной" функции идет с помощью обработчика очереди, то рекурсии быть не должно. То есть, просто при вызове animation() с конечной функцией, в очередь помещается "команда" движения объекта, а после нее "команда" вызова конечной функции, и код выполняется дальше. В параллель начинает движение объект, а при завершении движения вызовется конечная функция (возможно не сразу, а при очередном вызове jQuery.ready, который является Main Loop для всего jQuery).
Правильно ли я понял, что рекурсии не будет?
|
|
03.01.2011, 00:07
|
Аспирант
|
|
Регистрация: 02.01.2011
Сообщений: 56
|
|
Сообщение от B@rmaley.e><e
|
Рекурсия здесь даже если и есть, то по всей логике она должна быть хвостовой.
|
Да, и я не совсем понимаю, какой профит от хвостовой рекурсии, если она и используется вместо обычной? Стек вызовов будет той же глубины, а нас кроме глубины, по условию задачи, ничего не итересует. Так что рассуждение о хвостовой/нехвостовой рекурсии в данном случае не имеет смысла.
|
|
03.01.2011, 00:24
|
|
⊞ Развернуть
|
|
Регистрация: 11.01.2010
Сообщений: 1,810
|
|
Очередь используется только для анимаций (и то, если таковых назначено несколько) все операции, работающие с данными и не подразумевающие асинхронности выполняются незамедлительно. Сама анимация же происходит последовательным вызовом "функции-шага", которая проводит необходимые преобразования. Очереди в чистом виде здесь нет, но что-то похожее есть. Вызов callback'а же происходит на последнем шаге, когда дальше "шагать" уже некуда.
Сообщение от xintrea
|
Да, и я не совсем понимаю, какой профит от хвостовой рекурсии, если она и используется вместо обычной? Стек вызовов будет той же глубины, а нас кроме глубины, по условию задачи, ничего не итересует.
|
Хвостовой рекурсии не нужен стек.
|
|
03.01.2011, 10:14
|
Новичок на форуме
|
|
Регистрация: 19.02.2008
Сообщений: 9,177
|
|
Рекурсии не будет. Остальные вопросы отпадают.
|
|
03.01.2011, 11:26
|
Аспирант
|
|
Регистрация: 02.01.2011
Сообщений: 56
|
|
Сообщение от B@rmaley.e><e
|
Хвостовой рекурсии не нужен стек.
|
Любой рекурсии нужен стек, на то она и рекурсия. Хвостовой рекурсии не нужен стек только в случае, если она разложена на итерации. Но тогда она перестает быть рекурсией. Сомневаюсь, что интерпретатор яваскрипта на лету определяет вызовы хвостовых рекурсий и оптимизирует их в итеративную цепочку.
|
|
03.01.2011, 11:33
|
|
|
|
Регистрация: 27.12.2008
Сообщений: 4,201
|
|
Сообщение от B@rmaley.e><e
|
Хвостовой рекурсии не нужен стек.
|
во-первых, неизвестно, оптимизируют ли реализации хвостовую рекурсию. И если уж рассчитывать на глубокую рекурсию, то надо чтобы все реализации ее поддерживали. Во-вторых, там не return complete(...); и не факт, что оптимизатор догадается
xintrea,
1) у тебя будет непрерывная анимация в 500 шагов?
2) из чего сложилось твое впечатление?
Сообщение от xintrea
|
Любой рекурсии нужен стек
|
любой - не нужен, хвостовую рекурсию возможно оптимизировать
|
|
|
|