ChatGPT解决这个技术问题 Extra ChatGPT

Stop setInterval call in JavaScript

I am using setInterval(fname, 10000); to call a function every 10 seconds in JavaScript. Is it possible to stop calling it on some event?

I want the user to be able to stop the repeated refresh of data.


i
its4zahoor

setInterval() returns an interval ID, which you can pass to clearInterval():

var refreshIntervalId = setInterval(fname, 10000);

/* later */
clearInterval(refreshIntervalId);

See the docs for setInterval() and clearInterval().


How can you start it again after stopping with 'clearInterval()'? If I try to restart it I get 2x the setInterval running.
Me too Each time That i want to use SetInterval(MyFunction , 4000); it get faster and faster , each time 2x time faster :( how can i restart a setinterval??
SetInterval() does not change the speed that you pass it. If whatever it is doing speeds up each time that you call SetInterval(), then you have multiple timers which are running at the same time, and should open a new question.
Make sure you are really stopping it. Because of variable scoping, you may not have the right Id to call clearInterval. I have used window.refreshIntervalId instead of a local variable, and it works great!
I have started attaching the setInterval handle to its associated element (when relevant): $('foo').data('interval', setInterval(fn, 100)); and then clearing it with clearInterval($('foo').data('interval')); I'm sure there is a non-jQuery way to do it, too.
H
Hatchet

If you set the return value of setInterval to a variable, you can use clearInterval to stop it.

var myTimer = setInterval(...);
clearInterval(myTimer);

I don't see the difference between this and John's answer
late but, I think it is copied with some word difference nothing more clear than John's answer
B
Blauharley

You can set a new variable and have it incremented by ++ (count up one) every time it runs, then I use a conditional statement to end it:

var intervalId = null;
var varCounter = 0;
var varName = function(){
     if(varCounter <= 10) {
          varCounter++;
          /* your code goes here */
     } else {
          clearInterval(intervalId);
     }
};

$(document).ready(function(){
     intervalId = setInterval(varName, 10000);
});

I hope that it helps and it is right.


I was surprised to learn that this works clearInterval(varName);. I expected clearInterval to not work when passed the function name, I thought it required the interval ID. I suppose this can only work if you have a named function, as you can't pass an anonymous function as a variable inside of itself.
Actually I think it doesn't works. The code stop being executed because of the restriction on the counter, but the interval keeps firing varName(). Try to log anything after clearInterval() (inside the else clause) and you will see it being written forever.
$(document).ready(function(){ }); is jQuery, that's why it doesn't work. This should've been mentioned at least.
@OMGrant, In addition to an example that does not work, you have a variable named varName, which stores an unnamed function - wha?? You should change or take down this answer, IMHO.
As the MSN makes very clear, clearInterval expects an id not a function: developer.mozilla.org/en-US/docs/Web/API/WindowTimers/…. Due to this answer being incorrect as well as misleading I'm voting it down.
O
Onur Yıldırım

Already answered... But if you need a featured, re-usable timer that also supports multiple tasks on different intervals, you can use my TaskTimer (for Node and browser).

// Timer with 1000ms (1 second) base interval resolution.
const timer = new TaskTimer(1000);

// Add task(s) based on tick intervals.
timer.add({
    id: 'job1',         // unique id of the task
    tickInterval: 5,    // run every 5 ticks (5 x interval = 5000 ms)
    totalRuns: 10,      // run 10 times only. (omit for unlimited times)
    callback(task) {
        // code to be executed on each run
        console.log(task.name + ' task has run ' + task.currentRuns + ' times.');
        // stop the timer anytime you like
        if (someCondition()) timer.stop();
        // or simply remove this task if you have others
        if (someCondition()) timer.remove(task.id);
    }
});

// Start the timer
timer.start();

In your case, when users click for disturbing the data-refresh; you can also call timer.pause() then timer.resume() if they need to re-enable.

See more here.


a
assayag.org

In nodeJS you can you use the "this" special keyword within the setInterval function.

You can use this this keyword to clearInterval, and here is an example:

setInterval(
    function clear() {
            clearInterval(this) 
       return clear;
    }()
, 1000)

When you print the value of this special keyword within the function you outpout a Timeout object Timeout {...}


A
Aart den Braber

Why not use a simpler approach? Add a class!

Simply add a class that tells the interval not to do anything. For example: on hover.

var i = 0; this.setInterval(function() { if(!$('#counter').hasClass('pauseInterval')) { //only run if it hasn't got this class 'pauseInterval' console.log('Counting...'); $('#counter').html(i++); //just for explaining and showing } else { console.log('Stopped counting'); } }, 500); /* In this example, I'm adding a class on mouseover and remove it again on mouseleave. You can of course do pretty much whatever you like */ $('#counter').hover(function() { //mouse enter $(this).addClass('pauseInterval'); },function() { //mouse leave $(this).removeClass('pauseInterval'); } ); /* Other example */ $('#pauseInterval').click(function() { $('#counter').toggleClass('pauseInterval'); }); body { background-color: #eee; font-family: Calibri, Arial, sans-serif; } #counter { width: 50%; background: #ddd; border: 2px solid #009afd; border-radius: 5px; padding: 5px; text-align: center; transition: .3s; margin: 0 auto; } #counter.pauseInterval { border-color: red; }

 

I've been looking for this fast and easy approach for ages, so I'm posting several versions to introduce as many people to it as possible.


Doesn't seem really simpler to me... I also think it is cleaner to remove your intervals instead of keeping calls to functions that do nothing.
I don't agree. this.setInterval(function() { if(!$('#counter').hasClass('pauseInterval')) { //do something } }, 500); is all you have for code. Moreover, the check is the first thing you do, so it's very lightweight when it's being hovered. That is what this one is for: temporarily pausing a function. If you want to terminate it indefinitely: of course you remove the interval.
This amounts to polling and is generally discouraged. It will wake up the CPU from low power states just to do a (likely) useless check. It also delays feedback from immediate to between 0 and 500 ms in this example.
I entirely don't agree with you, even while I wrote the code 2 years ago. The counter must be there anyway, because the OP asked for it. Sure, if you're using this to stop the counter after pressing a button, for example, this would be a sub-optimal solution, but just for a pause when hovering, this is one of the simplest solutions available.