-1

I want to use recursion in JavaScript to produce an infinite loop. In fact, I desire to give an image a come-and-go effect, endlessly.

Let's take a look at some code first :

function lightening(){
    $('#pic_holder').fadeOut(250).fadeIn(250);
    setTimeout('lightening', 250);
}

This function, as it's written, should

  • apply the fadeOut(250) and fadeIn(250) effects ;
  • engage the setTimeout function which in its turn must call recursively the lightening function, henceforth re-applying the [fadeOut-fadeIn effect and setTimeout] block of code.

This, you'll agree, should go ad infinitum, but it doesn't.

Here's the full test code, with HTML, as you can notice, it applies the fadeOut-fadeIn effect only once.

What am I doing wrong ?

11
  • 2
    Note that the calls to "fadeOut" and "fadeIn" will return immediately, even though the effect will take 500 milliseconds. If you start the next cycle in 250 milliseconds, you'll be building up a backlog. Commented Jul 16, 2013 at 15:05
  • 5
    Also note that the code in your question is not recursive. Asynchrony and recursion are different things entirely. Commented Jul 16, 2013 at 15:06
  • @FrédéricHamidi I would say it's both. Commented Jul 16, 2013 at 15:09
  • @basilikum - How so? According to wikipedia: Recursion in computer programming is exemplified when a function is defined in terms of simpler, often smaller versions of itself. The solution to the problem is then devised by combining the solutions obtained from the simpler versions of the problem. Commented Jul 16, 2013 at 15:12
  • 1
    @basilikum - Also from wikipedia: The main disadvantage is often that the algorithm may require large amounts of memory if the depth of the recursion is very large.. This seems to imply a stack (I'm ignoring TCO here), where each invocation returns state. This is just emulating setInterval, which I hope we can agree is not recursion. Commented Jul 16, 2013 at 15:15

4 Answers 4

7

What you really should do is this:

function lightening(){
  $('#pic_holder').fadeOut(250).fadeIn(250, lightening);
}

That'll make the next cycle start when the fade-in has completed. Mixing your own timeouts with timeouts implied by jQuery animation calls is tricky and usually unnecessary. In your case, you're starting a new cycle halfway through a previous one, which really won't take effect until 250 milliseconds later.

Sign up to request clarification or add additional context in comments.

1 Comment

This is sexy. Nice answer.
6

The first argument to setTimeout can either be:

  • a function to be called; or
  • a string of JavaScript to be executed

Your function isn't being called, because you just have its name in a string. Remove the single quotes.

function lightening(){
    $('#pic_holder').fadeOut(250).fadeIn(250);
    setTimeout(lightening, 250);
}

See the Mozilla Documentation for proper usage.

1 Comment

and the timer interval should probably be 500 milliseconds, not 250
3

Instead of using 2 competing timers that will either have intermittent bugs or have to be too generous, use the callback:

function lightening(){
    $('#pic_holder').fadeOut(250).fadeIn(250, lightening);
}

1 Comment

+1 for using callback. I removed my answer suggesting this since yours came first. Here are the notes I had added to my post: This solution allows for the fact that the timings aren't guaranteed. A timer guarantees a MINIMUM amount of time until an event happens, but based on processing, it could be more. Similarly, you're not guaranteed that the animations start immediately. This might be splitting hairs, but I think it's worth at least noting and adding to the answer list.
1

Remove quote.

setTimeout(lightening, 250);

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.