Javascript-форум (https://javascript.ru/forum/)
-   jQuery (https://javascript.ru/forum/jquery/)
-   -   jQuery, функция animate(), рекурсия (https://javascript.ru/forum/jquery/14147-jquery-funkciya-animate-rekursiya.html)

xintrea 02.01.2011 23:07

jQuery, функция animate(), рекурсия
 
Здравствуйте!


Есть некая игра (что-то наподобе шахмат), для которой на jQuery пишу "плейер". Плейер предназначен для того, чтобы показывать "запись" игры. Игра на двух человек, сначала ходит фигура одного игрока, потом другого, и т.д. Плейеру скармливаются все ходы в игре, он в соответствие с этими ходами перемещает фигуры на экране.

Перемещение фигур должно поисходить так: движется одна фигура, когда она закончила движение, должна перемещаться следующая, и т.д.

В jQuery есть функция animate(), в последнем параметре которой можно указать "конечную" функцию, которая вызывается в конце движения фигуры. Я могу указывать в качестве конечной функции метод начала обработки нового шага, next_step() например.

Но, у меня складывается впечатление, что это создаст рекурсию. Так как в next_step() снова будет вызвана animate() для следующей фигуры, и т.д. Помню, что совсем недавно в браузерах были какие-то ограничения на глубину стека вызовов. То ли 64, толи 100. А в моей игре возможно и 500 ходов и более.


Всвязи с вышеизложенным, вопросы:

1. Действительно ли в вышеописанном случае будет рекурсия?

2. Какие ограничения в JavaScript на стек вызовов в современных браузерах?

3. Как организовать плейер так, чтобы небыло рекурсии? У меня есть предположение сделать машину состояний, и в качестве конечной функции для animate() указать метод, переключащий некий флаг в состояние "ход закончен". Но тогда надо организовывать основной цикл, который будет отслеживать флаги, а его можно организовать только через setTimeout(), что даже при обработке 10 раз в секунду может дать большую нагрузку на браузер.


То есть, мне бы хотелось просто вызывать обработку следующего хода в момент, когда движение фигуры на текущем ходе закончено. Как это сделать?

B@rmaley.e><e 02.01.2011 23:18

Цитата:

Сообщение от xintrea
1. Действительно ли в вышеописанном случае будет рекурсия?

Возьмите и посмотрите. Код jQuery открыт (hint: jQuery.fx.prototype.step, функция будет лежать в this.options.complete).
Рекурсия здесь даже если и есть, то по всей логике она должна быть хвостовой. Не говоря уже о том, что callback будет вызван в другой момент времени (setTimeout / setInterval постарается), когда функция, начавшая анимацию, будет уже давным-давно выполнена.

xintrea 02.01.2011 23:21

> Возьмите и посмотрите. Код jQuery открыт.

Можно было и не отвечать, коль вы не знаете ответа.

x-yuri 02.01.2011 23:39

Цитата:

Сообщение от xintrea
Можно было и не отвечать, коль вы не знаете ответа.

прочитай ответ еще раз...

Цитата:

Сообщение от xintrea
Но, у меня складывается впечатление, что это создаст рекурсию.

паранойя?

xintrea 02.01.2011 23:57

Цитата:

Сообщение от B@rmaley.e><e (Сообщение 86020)
Возьмите и посмотрите. Код jQuery открыт (hint: jQuery.fx.prototype.step, функция будет лежать в this.options.complete).
Рекурсия здесь даже если и есть, то по всей логике она должна быть хвостовой. Не говоря уже о том, что callback будет вызван в другой момент времени (setTimeout / setInterval постарается), когда функция, начавшая анимацию, будет уже давным-давно выполнена.

Насколько я понял, весь jQuery работает на основе очереди, и для каждого обрабатываемого селектора создается очередь. В очередь помещаются "команды", что нужно делать в данный момент времени и информация, на каком этапе находится выполнение "команды". Как только "команда" выполнена, она удаляется из очереди, и начинается выполнение следущей "команды".

Получается, что если вызов "конечной" функции идет с помощью обработчика очереди, то рекурсии быть не должно. То есть, просто при вызове animation() с конечной функцией, в очередь помещается "команда" движения объекта, а после нее "команда" вызова конечной функции, и код выполняется дальше. В параллель начинает движение объект, а при завершении движения вызовется конечная функция (возможно не сразу, а при очередном вызове jQuery.ready, который является Main Loop для всего jQuery).

Правильно ли я понял, что рекурсии не будет?

xintrea 03.01.2011 00:07

Цитата:

Сообщение от B@rmaley.e><e (Сообщение 86020)
Рекурсия здесь даже если и есть, то по всей логике она должна быть хвостовой.

Да, и я не совсем понимаю, какой профит от хвостовой рекурсии, если она и используется вместо обычной? Стек вызовов будет той же глубины, а нас кроме глубины, по условию задачи, ничего не итересует. Так что рассуждение о хвостовой/нехвостовой рекурсии в данном случае не имеет смысла.

B@rmaley.e><e 03.01.2011 00:24

Очередь используется только для анимаций (и то, если таковых назначено несколько) все операции, работающие с данными и не подразумевающие асинхронности выполняются незамедлительно. Сама анимация же происходит последовательным вызовом "функции-шага", которая проводит необходимые преобразования. Очереди в чистом виде здесь нет, но что-то похожее есть. Вызов callback'а же происходит на последнем шаге, когда дальше "шагать" уже некуда.
Цитата:

Сообщение от xintrea
Да, и я не совсем понимаю, какой профит от хвостовой рекурсии, если она и используется вместо обычной? Стек вызовов будет той же глубины, а нас кроме глубины, по условию задачи, ничего не итересует.

Хвостовой рекурсии не нужен стек.

Kolyaj 03.01.2011 10:14

Рекурсии не будет. Остальные вопросы отпадают.

xintrea 03.01.2011 11:26

Цитата:

Сообщение от B@rmaley.e><e (Сообщение 86032)
Хвостовой рекурсии не нужен стек.

Любой рекурсии нужен стек, на то она и рекурсия. Хвостовой рекурсии не нужен стек только в случае, если она разложена на итерации. Но тогда она перестает быть рекурсией. Сомневаюсь, что интерпретатор яваскрипта на лету определяет вызовы хвостовых рекурсий и оптимизирует их в итеративную цепочку.

x-yuri 03.01.2011 11:33

Цитата:

Сообщение от B@rmaley.e><e
Хвостовой рекурсии не нужен стек.

во-первых, неизвестно, оптимизируют ли реализации хвостовую рекурсию. И если уж рассчитывать на глубокую рекурсию, то надо чтобы все реализации ее поддерживали. Во-вторых, там не return complete(...); и не факт, что оптимизатор догадается

xintrea,
1) у тебя будет непрерывная анимация в 500 шагов?
2) из чего сложилось твое впечатление?

Цитата:

Сообщение от xintrea
Любой рекурсии нужен стек

любой - не нужен, хвостовую рекурсию возможно оптимизировать


Часовой пояс GMT +3, время: 11:55.