简体   繁体   中英

Break setTimeout function inside foreach loop

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);
                }); 

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.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM