-->

stopping dynamically generated setInterval

2019-07-24 18:14发布

问题:

I am generating multiple charts each with their own setInterval to refresh the data. I have it set to clearInterval when the dynamically generated container is removed - but if I reload and it has the same id the old setInterval continues to run. Is there a way to set a dynamically named setInterval that can be stopped when the replacement is generated?

Right now I'm using:

function generateChart(data, location){
    var chart = new Highcharts.Chart({
        // blah blah blah
    }, function(chart){
        setInterval(function(){
            if($('#'+location).length){
                // I'm doing stuff every minute
            }else{
                clearInterval();
            }
        },60000);
    });
}

What happens is, the location is a randomly generated string that becomes the element ID for the container for the Highchart and if they user saves the chart it becomes the unique identifier. If the user updates the chart that's saved and reloads the chart, the old one gets .removed() and the new one generated in its place. Now the new one has the same element ID as the old one and since the old interval finds the container it wants it attempts to continue updating - which is can't since its chart went poof.

is there a way to set a dynamic variable I can use for setInterval so that I can clearInterval on it?

var blob+location = setInterval(function(){ ...

and then

clearInterval(blob+location);

回答1:

You can just use an object:

var myObj = {};

var location = "somevalue";

myObj[location] = setInterval(...

clearInterval(myObj[location]);


回答2:

ok - since I couldn't seem to wrap my head around some of your answers I decided to go low tech.

function genToken(){
    var num = Math.floor(Math.random() * 10000);
    var token = 't-' + num;
    return token;
}

function genLocation(){
    var chartToken = genToken();
    var newChart = '<div id="'+location+'" data-token="'+chartToken+'"></div>';
    $('#chartHome').append(newChart);
}

// inside my chart function

var token = $('#'+location).data('token');
setInterval(function(){
    if( $('[data-token="'+token+'"]').length ){
        // still there - keep going
    }else{
        // all gone - time to stop
        clearInterval();
    }
},60000);

now when I do:

$('#'+location).remove();

the token also vanishes and won't be the same if I generate a new chart with the same location id.



回答3:

Stop using setInterval, use setTimeout instead (How do I execute a piece of code no more than every X minutes?):

function generateChart(data, location) {

    var element = $('#'+location);

    var chart = new Highcharts.Chart({
        // blah blah blah
    }, foo);

    var foo = function() {

        if(element){

            // I'm doing stuff every minute

            setTimeout(foo, 6000);
        }

    };

}

To stop it, just avoid the setTimeout or make element = null.

Maybe my code is a little bit wrong (I'm getting sleep right now), but the thing is to use setTimeout and closures.

If inside foo, something longs more than 6 seconds you will be in troubles since setTimeinterval will call it again, please watch http://www.youtube.com/watch?feature=player_detailpage&v=i_qE1iAmjFg#t=462s , so, this way you ensure that this will run 6 seconds after the last completed stuff.

I'll let this example here to posterity:

http://jsfiddle.net/coma/vECyv/2/

var closure = function(id) {

    var n = 0;
    var go = true;

    $('#' + id).one('click', function(event) {

        go = false;

    });

    var foo = function() {

        if(go) {

            console.log(id, n++);
            setTimeout(foo, 1000);

        }

    };

    foo();
};

closure('a');
closure('b');