0

I am trying to break the setTimeout function which is started on page load. So what I am doing here is, If I click on the button then I making flag value to true and setTimeout should break which isn't happening here. This setTimeout function is inside the for each loop. Below is my code.

                rData[0].dt.forEach(function(d, i) {
                    setTimeout(function() {
                        if(flag === "false"){
                            console.log(flag);
                            reserRadius(i); //here I am changing radius of circle
                        }else{
                            console.log(flag);
                            clearTimeout();
                            return;
                        }   

                    }, i * 2000);
                }); 
4
  • clearTimeout expects an id returned from setTimeout, but where you have it doesn't make sense, because by the time the function is evaluated the timeout is already completed and there is no reason to call clearTimeout Commented Aug 11, 2016 at 19:59
  • 4
    It is unclear what you exactly want your code to do. You cannot remove timeout inside itself, because when executed, it is already removed. It will be useful to post a JSFiddle snippet in your question. Commented Aug 11, 2016 at 20:04
  • I have animation code which is running inside this setTimeout function. I want this animation to stop if I hover over a particular region, so I am trying to stop it with the help of button. Commented Aug 11, 2016 at 20:08
  • @castis I have already tried assigning to a variable but still not able to break the loop. Commented Aug 11, 2016 at 20:10

2 Answers 2

4

Instead of creating all timeouts in one go, only create them when needed. This way you don't have to clear any of them when you have determined to stop:

(function repeat(list, i) {
    if (i >= list.length) return; // nothing (more) to do 
    var d = list[i]; // do you need d at all??
    setTimeout(function() {
        if(flag === "false"){
            console.log(flag);
            reserRadius(i); //here I am changing radius of circle
            repeat(list, i+1); // schedule next timeout only now.
        }else{
            console.log(flag);
            // Don't schedule next timeout. This breaks the "loop".
        }   
    }, 2000); // trigger 2 seconds from now. Note: no multiplying anymore.
})(rData[0].dt, 0); // pass initial values: the array and index.

In your version of the code, you would have to keep the id values returned by all setTimeout calls, and then pass them all (or at the least the remaining ones) to clearTimeout, one by one. This would make your code quite cumbersome. I think the above is a more efficient approach.

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

Comments

0

setTimeout cannot be stopped from its callback itself. setTimeout returns a timeoutId which can be passed to clearTimeout which in turn will stop that particualr timer.

One way to stop all such timers is to create an array of timeoutIds and make changes as following.

var timerIds = [];
rData[0].dt.forEach(function(d, i) {
    timerIds.push(setTimeout(function(){
        if(flag === "false"){
            console.log(flag);
            reserRadius(i); //here I am changing radius of circle
        }
        else{
            console.log(flag);
        }
    }, i * 2000));
}); 

function stopTimeouts(){
    timerIds.forEach(function(id){
        clearTimeout(id);
    }
}
function codeThatMightChangeFlag(callback) {
    // do a bunch of stuff
    if (condition happens to change flag value) {
        // call the callback to notify other code
        stopTimeouts();
    }
}

Refer: Clear array of setTimeout's and Javascript - wait until flag=true

Comments

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.