1

I'm trying to do something like that :

I want to call the doSomething() function only when the tab has loaded class (it may take 3 or 5 seconds).

function addInfosSinistre(msg){
     addInfosSinistreRecursive(msg, 0);
}

function addInfosSinistreRecursive(msg, nbCalls) {
    if ($("#tab").hasClass('loaded')) {
        doSomething();
    }else if (nbCalls < 10) {
        setTimeout(addInfosSinistreRecursive(msg, nbCalls+1),500);
    }
}

This is not working, it seems like the timer doesn't work. Is there something wrong here ?

user3469203
  • 537
  • 1
  • 9
  • 22
  • 1
    Yes, there's something wrong, you're calling the function, not referencing it, so the timer doesn't work, but that's not the main issue, if you're waiting for something to load, you shouldn't be using timeouts, you should be using callbacks, events or whatever, but without knowing how and what you're waiting for, we can't help you. And no, a class attribute doesn't really load, there must be something else going on ? – adeneo Sep 17 '14 at 12:01
  • possible duplicate of [Calling functions with setTimeout()](http://stackoverflow.com/questions/3800512/calling-functions-with-settimeout) – Qantas 94 Heavy Sep 17 '14 at 12:04

2 Answers2

2

What you actually do, is to execute the function addInfosSinistreRecursive and the pass the return value to setTimeout(). What you actually want to do is to pass a function reference.

One way of doing so is to create a closure for the variables like this:

function addInfosSinistreRecursive(msg, nbCalls) {

  function timeoutHandler(){
    if ($("#tab").hasClass('loaded') ) {
        doSomething();
    }else if (nbCalls < 10) {
        nbCalls += 1;
        setTimeout( timeoutHandler, 500 );
    }
  }

  // first execution
  timeoutHandler();

}

The function timeoutHandler() can reference the parameters to addInfosSinistreRecursive() and has no parameters of its own. Hence you can pass a reference to it to setTimeout().

Sirko
  • 72,589
  • 19
  • 149
  • 183
1

Yes, there's definitely something wrong here. You're immediately calling the function and passing undefined to setTimeout() instead of giving it a function to call. This would do what you are trying to do:

function addInfosSinistreRecursive(msg, nbCalls) {
    if ($("#tab").hasClass('loaded')) {
        doSomething();
    }else if (nbCalls < 10) {
        setTimeout(addInfosSinistreRecursive.bind(this, msg, nbCalls + 1), 500);
    }
}

But the question is why are you trying to do this? It seems like a convoluted way to do whatever it is you are trying to accomplish. You should probably be using an event somewhere when the tab is changed rather than recursively looping and waiting for the tab to change.

JLRishe
  • 99,490
  • 19
  • 131
  • 169
  • Yes, I assume an event must be a better way... but I'm quite a beginner is JS, so... – user3469203 Sep 17 '14 at 12:27
  • sirko's answer is working, so I have to learn about event... thanks – user3469203 Sep 17 '14 at 12:50
  • @user3469203 Did you try my answer? It's a lot more concise and should have essentially the same behavior as Sirko's. – JLRishe Sep 17 '14 at 13:01
  • Sorry I didn't try. I've tried sirko's one first, and it works, so. – user3469203 Sep 18 '14 at 12:17
  • @user3469203 Ok... You're of course free to choose whichever answer you like, but generally the rule of thumb is to choose the best answer, not the first one you try that works. But do as you will. – JLRishe Sep 18 '14 at 13:45