How do I clear all intervals?
Asked Answered
P

6

70

I am using

varName = setInterval(function() { ... }, 1000);

to set a couple of intervals in a jquery plugin that I'm writing, but when the plugin is reloaded I need to clear those intervals. I tried storing them in variables, like this:

(function($){
$.mosaicSlider = function(el) {
    var base = this;        
    var transitionInterval, mainInterval;

...

base.init = function() {
    mainInterval = setInverval(function() { ... }, 1000);
}

base.grid = function() {
    this.transition() = function() {
         transitionInterval = setInterval(function(...) {
    }
}

base.init();

And I tried killing those intervals in the base.init() function, like this:

clearInterval(transitionInterval);
clearInterval(mainInterval);

And like this:

window.oldSetInterval = window.setInterval;
window.setInterval = new function(func, interval) {  }
Pauperize answered 26/12, 2011 at 11:57 Comment(3)
try add var transitionInterval, mainInterval; out of mosaicSlider function after (function($){ .Trotyl
possible duplicate of How to clearInterval with unknown ID?Garganey
Possible duplicate of How to stop all timeouts and intervals using javascript?Flytrap
H
94

You can find the "highest" timer identifier by creating a new timer that does "nothing" (by giving it an empty function to run, scheduled to run decades in the future), and then clear every timer between ids 1 and that identifier, like so:

// Get a reference to the last interval + 1
const interval_id = window.setInterval(function(){}, Number.MAX_SAFE_INTEGER);

// Clear any timeout/interval up to that id
for (let i = 1; i < interval_id; i++) {
  window.clearInterval(i);
}

However, note that this is not guaranteed to work: the HTML standard does not actually prescribe how timeout/interval identifiers get allocated, so the assumption that we'll get a reference to the "last interval identifier + 1" is merely that: an assumption. It might be true for most browsers at the time of this answer, but there is no guarantee that's that will still be the case even in the next version of the same browser.

Hervey answered 26/12, 2011 at 12:0 Comment(10)
This snippet DID work, but it causes some weird side effects. Here's the plugin: nikolaydyankov.com/Dev/mosaic - try playing with the settings below and see how the transitions simply stop working. I tried to debug this, logged all of the variables, tested all new intervals and nothing. It just won't work.Pauperize
This is not a good idea. The specification does not guarantee any specific order for the handles, only that they are numeric and unique.Howlett
The spec states "Let handle be a user-agent-defined integer that is greater than zero that will identify the timeout to be set by this call." That is, positive and unique. No other guarantees.Howlett
Bad idea, for the reason @JanDvorak specified and because it will also stop intervals that were not created by your code.Antoninus
Additionally, window.setInterval('', 9999); returns "undefined" for me. Even with an empty function passed instead, the above still appliesHowlett
while in theory the specification does not guarantee a specific order, as a practical answer, based on what browsers do in reality, this answer is just fine. Firefox, Webkit browsers and IE all generate sequential interval numbers (presumably because that's the easiest way to meet the spec. It would be insane to come up with a better unique sequence than an incremented uuid)Wimple
Initially this worked for me, but as my app got more complicated it caused all sorts of problems. For example, jQuery's fadeOut function uses intervals, so due to a race condition the fadeOut callback function was never called, so be mindful when using this shotgun approach!Illegible
This is a welcoming message for all sorts of hard-to-catch bugs ... It's better if you keep track of what intervals you created in an array or an object, and only clear those ...Thorncombe
NOTE Depending on the implementation, clearInterval may also clear timeouts, and clearTimeout may also clear intervals.Ineslta
Not just depending on the implementation: the HTML standard clearly states that they do the exact same thing. It doesn't matter whether a timer is associated with a timeout or an interval. Also, as upvoted as this answer is: it's incorrect. The HTML standard clearly states that the actual numbers you get from setTimeout/setInterval are implementation specific meaning there is literally no requirements on the logic for numbering, and the idea behind this answer is something you explicitly can't rely on. It just "happens to work, in this browser".Wimple
V
74

Store 'em in an object. Since you're the only one making these intervals, and you know what they are, you can store them and later mess with them as you wish. I'd create an object dedicated for just that, something like:

var interval = {
    // to keep a reference to all the intervals
    intervals : new Set(),
    
    // create another interval
    make(...args) {
        var newInterval = setInterval(...args);
        this.intervals.add(newInterval);
        return newInterval;
    },

    // clear a single interval
    clear(id) {
        this.intervals.delete(id);
        return clearInterval(id);
    },

    // clear all intervals
    clearAll() {
        for (var id of this.intervals) {
            this.clear(id);
        }
    }
};

Your first question might be

Why make a separate object for just that?

Well Watson, it's to keep your hand-made intervals related to your plugin/project away from prying eyes, so you won't mess with other intervals being set in the page not related to your plugin.

Yes, but why can't I store it inside the base object?

You most certainly can, but I think this way is much cleaner. It separates the logic you do in your base with the weird timeout logic.

Why did you store the intervals inside a Set and not an array?

Faster access and a little bit of cleaner code. You can go either way, really.

Vogler answered 26/12, 2011 at 13:6 Comment(3)
I used an array as a data structure, but anyhow, this is the correct approach. One can even have different interval "wrappers" in case you don't want to kill all. Good answer!Thorncombe
Couldn't you just call this.intervals.clear() within the clearAll() method rather than looping through the whole collection and manually removing all elements by calling the delete() method instead?Intercom
No - this.intervals.clear() is Set.prototype.clear(), which just empties the Set itself, it does not clear the intervals within that set. Rolled back edits implementing that suggestion.Hampshire
R
21

Intialize Timer and set it as window object. Window.myInterval will hold the ID of the Timer.

like window.myInterval = setInterval(function() { console.log('hi'); }, 1000);

To clear Interval you can write like

if(window.myInterval != undefined && window.myInterval != 'undefined'){
    window.clearInterval(window.myInterval);
    alert('Timer cleared with id'+window.myInterval);
}
Reality answered 23/2, 2016 at 7:45 Comment(0)
G
4

When you set an interval, you get a pointer to it. To clear all intervals, you'll need to store all of them:

// Initially
var arr = [];
arr.push(setInterval(function () {
    console.log(1);
  }, 1000));
arr.push(setInterval(function () {
    console.log(2);
  }, 1000));
arr.push(setInterval(function () {
    console.log(3);
  }, 1000));
  

Following loop will clear all intervals

// Clear multiple Intervals
  arr.map((a) => {
    console.log(a)
    clearInterval(a);
    arr = [];
  })
Guildhall answered 30/7, 2020 at 22:47 Comment(3)
If you're not returning a value nor making another array, use forEach instead of mapPeruse
@NikolaDiklich Why is that? Just asking out of curiousity.Intercom
Because it's the core semantic difference between map and forEach. You use map to transform the array into another array of the same length (and most commonly assign it to some variable), but forEach to perform an operation on every item inside the array. We use forEach if it doesn't get assigned to anything.Peruse
B
0

For Node.js

There's no possible hack to clear all intervals without keeping track of them. So let's say you want to perform a clear to make sure the service terminates graciously or in any other scenario you want to kill all running intervals.

Solution

Create a Singleton that handles all setInterval in the system and use it to create the intervals, then, when necessary call its clearAllIntervals method, invalidating all of them at once without having to keep track of them individually.

Singleton Implementation (Suggestion for TS, in JS just remove typings)

class IntervalManager {
  private static instance: IntervalManager;
  private intervals: Set<NodeJS.Timeout>;

  private constructor() {
    this.intervals = new Set<NodeJS.Timeout>();
  }

  public static getInstance(): IntervalManager {
    if (!IntervalManager.instance) {
      IntervalManager.instance = new IntervalManager();
    }

    return IntervalManager.instance;
  }

  public setInterval(callback: () => void, delay: number): NodeJS.Timeout {
    const id = setInterval(callback, delay);
    this.intervals.add(id);
    return id;
  }

  public clearInterval(id: NodeJS.Timeout): void {
    clearInterval(id);
    this.intervals.delete(id);
  }

  public clearAllIntervals(): void {
    for (const id of this.intervals) {
      clearInterval(id);
    }
    this.intervals.clear();
  }
}

export default IntervalManager;

Usage (can be used in any and multiple files)

import IntervalManager from './IntervalManager';

const intervalManager = IntervalManager.getInstance();

// Set an interval
const id = intervalManager.setInterval(() => {
  console.log('Hello, world!');
}, 1000);

// Clear a specific interval
intervalManager.clearInterval(id);

// Set multiple intervals
intervalManager.setInterval(() => {
  console.log('Hello, world!');
}, 1000);

intervalManager.setInterval(() => {
  console.log('Hello again, world!');
}, 2000);

// Clear all intervals
intervalManager.clearAllIntervals();
Brooklyn answered 16/6, 2023 at 22:19 Comment(0)
S
-1

This worked for me:

window.stop();
Sottish answered 25/10, 2022 at 6:32 Comment(1)
Your answer could be improved by adding more information on what the code does and how it helps the OP.Onofredo

© 2022 - 2024 — McMap. All rights reserved.