2013-12-23 3 views
3

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

function animateLeft(obj, top){ 
    if(top >= 300){   
     obj.style.visibility = 'visible'; 
     return; 
    } 
    else { 
     var box = obj; 
     box.style.marginLeft = top + "px"; 
     box.style.marginTop = top + "px"; 
     setTimeout(function(){ 
      animateLeft(obj, top + 1); 
     }, 25) 
    } 
} 
function animateMe() { 
    animateLeft(document.getElementById('inner-rectange'), 0); 
} 
+0

У меня была проблема, и Я использовал рекурсию для их решения. – corsiKa

+1

Возможно, было бы полезно указать, что эта проблема может быть решена и в чистом CSS – Simone

+0

@simone Я пытаюсь создать анимацию, поэтому мне нужно добавить задержку, не уверен, как это можно сделать с помощью css – Jay

ответ

3

Вы на самом деле не используя рекурсию, так как вы вызываете метод от setTimeout.

К тому времени функция повторно выполняет начальное будет вышел .. (выполнение каждый не блокирует следующую)

Использование рекурсии в JavaScript для вещей, которые манипулируют DOM является неправильным, так как перекраивания страницы будет происходить только после завершения всей рекурсии. Таким образом, вы потеряете все промежуточные шаги анимации и переходите с 1-го шага к последнему.


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

Просто установите transition property узла DOM через CSS, а затем изменить свойства, применяя новый класс (или непосредственно через JavaScript)

div{ 
    margin-left:0; 
    margin-top:0; 

    -moz-transition:margin 2s linear; 
    -webkit-transition:margin 2s linear; 
    transition:all 2s linear; 
} 

.move{ 
    margin-left:100px; 
    margin-top:100px; 
} 

Смотрите демо наhttp://jsfiddle.net/gaby/rm3EP/

(при применении move класса к div CSS будет анимировать изменение задворки ..)

+0

Значит ли это, что рекурсивные функции задействованы в фоновом режиме, когда есть задержка с настройкой? – Jay

+1

Нужный тайм-аут по определению вызовет обратный вызов *** после того, как *** указанное вами время прошло (* и без блокировки другого кода от выполнения *) –

+0

ok Что произойдет, если я удалю функцию setTimeout? он будет рекурсивным, чем правильным? – Jay

1

Я бы не использовал рекурсию для этого. Я даже не уверен, что это не будет сделано лучше с помощью jQuery или чего-то еще.

Я думаю, что рекурсия сначала, когда я имею дело с рекурсивной структурой данных, подобной дереву, но не для такого случая.

+0

Или многомерный массив объектов или что-то еще –

5

Использование setTimeout означает, что ваш код не рекурсивно вызывает функцию анимации напрямую. Это заставит функцию многократно вызывать, но не приведет к созданию глубокого стека.

Для анимации это вполне разумный подход (есть более эффективные подходы, такие как requestAnimationFrame, но разумно!)

+0

Его анимация, которую я пытаюсь создать, так что settimeout добавит только задержку. – Jay

+0

@jay взгляните на http://underscorejs.org/#defer – spojam

+0

Я не думаю, что это ABA рекурсивный, поскольку стек никогда не будет иметь одну и ту же функцию A в нем более одного раза. Использование 'setTimeout' таким образом означает, что функция будет вызываться снова и снова, но никогда от нее (или некоторая функция, которую она вызывает), которая будет генерировать рекурсию ABA) – Toote

0

Вашего примера является более замедленной resursive функции а. Из-за setTimeout проблем с памятью не должно быть. Это текущее animateLeft закончится, а позже на следующее пойдет.

0

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

Смежные вопросы