6

I'm writing a little jQuery component that animates in response to button presses and also should go automatically as well. I was just wondering if this function recursive or not, I can't quite work it out.

function animate_next_internal() {

  $('#sc_thumbnails').animate(
    { top: '-=106' }, 
    500, 
    function() {
      animate_next_internal();
    }
  ); 
}  

My actual function is more complicated to allow for stops and starts, this is just a simplified example.

EDIT It could either overflow the stack or not, depending on how the events are handled internally. Possibilities:

  1. animate() directy calls the done callback, in which case an overflow is inevitable.

  2. animate() schedules the callback for calling by some external dispatching mechanism and then terminates, in which case it will never overflow.

NXT
  • 1,855
  • 2
  • 18
  • 36

2 Answers2

9

I initially suspected that it would overflow the memory, but I wrote a short test to confirm

function test(){
  $(".logo img").css("position", "absolute");
  $(".logo img").css("top", "100px");
  $(".logo img").animate({top:0}, 500, function(){
      test();
      console.log("exits here");
  });
}

test();

and surprisingly, I saw

exits here
exits here
exits here
exits here
exits here
...

in my logs. Looks like "animate() schedules the callback for calling by some external dispatching mechanism and then terminates, in which case it will never overflow." is the right answer

Mark Schultheiss
  • 32,614
  • 12
  • 69
  • 100
sjobe
  • 2,817
  • 3
  • 24
  • 32
  • 1
    +1 Since your setting a callback function this is not the same as calling the function inside itself. this is not true recursion. – Samuel Apr 25 '10 at 02:25
  • 1
    Hi, thanks for taking the time to try that out. I think you nailed it. – NXT Apr 25 '10 at 19:25
  • 1
    You're certainly right that it works out and your test to prove it is fine. If you'd also want to know _why_ this works, you will have to understand the concept of **Queues**, implemented in jQuery by the methods [`.queue()`](http://api.jquery.com/queue/) and [`.dequeue()`](http://api.jquery.com/dequeue/). All of this is explained very well and with examples in [this answer](http://stackoverflow.com/a/3314877/1062304) to another question. – bfncs May 27 '15 at 09:14
0

I would expect that such an implementation will overflow the call stack. Unless you simplified it out, you should have some kind of terminal condition that causes the function to back out of the recursion. You probably need something like this:

function animate_next_internal() {

  if ( some_condition ) return;

  $('#sc_thumbnails').animate(
    { top: '-=106' }, 
    500, 
    function() {
      animate_next_internal();
    }
  ); 
}  

Where some_condition is something related to the recursion -- maybe when #sc_thumbnails actual top reaches some limit like 0 on the page or within its parent.

BJ Safdie
  • 3,399
  • 23
  • 23
  • Thank you for your reponse but you didn't read the post -- I posted simplified code for clarity. – NXT Apr 25 '10 at 00:04