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 ?

2
  • 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 ? Commented Sep 17, 2014 at 12:01
  • possible duplicate of Calling functions with setTimeout() Commented Sep 17, 2014 at 12:04

2 Answers 2

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().

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

Comments

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.

5 Comments

Yes, I assume an event must be a better way... but I'm quite a beginner is JS, so...
sirko's answer is working, so I have to learn about event... thanks
@user3469203 Did you try my answer? It's a lot more concise and should have essentially the same behavior as Sirko's.
Sorry I didn't try. I've tried sirko's one first, and it works, so.
@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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.