javascript: Clear all timeouts?

Is there a way to clear all time outs from a given window? I suppose the timeouts are stored somewhere in the window object but couldn’t confirm that.

Any cross browser solution is welcome.

They are not in the window object, but they have ids, which (afaik) are consecutive integers.

So you may clear all timeouts like so:

var id = window.setTimeout(function() {}, 0);

while (id--) {
    window.clearTimeout(id); // will do nothing if no timeout with id is present
}

I think the easiest way to accomplish this would be to store all the setTimeout identifiers in one array, where you can easily iterate to clearTimeout() on all of them.

var timeouts = [];
timeouts.push(setTimeout(function(){alert(1);}, 200));
timeouts.push(setTimeout(function(){alert(2);}, 300));
timeouts.push(setTimeout(function(){alert(3);}, 400));

for (var i=0; i<timeouts.length; i++) {
  clearTimeout(timeouts[i]);
}

This is very late… but:

Basically, setTimeout/setInterval ID’s go in consecutive order, so just create a dummy timeout function to get the highest ID, then clear interval on all the IDs lower than that.

const highestId = window.setTimeout(() => {
  for (let i = highestId; i >= 0; i--) {
    window.clearInterval(i);
  }
}, 0);

I have an addition to Pumbaa80’s answer that might be useful for someone developing for old IEs.

Yes, all major browsers implement timeout ids as consecutive integers (which is not required by specification). Althrough the starting number differs form browser to browser. It seems that Opera, Safari, Chrome and IE > 8 starts timeout ids from 1, Gecko-based browsers from 2 and IE <= 8 from some random number that is magically saved across tab refresh. You can discover it yourself.

All that meens that in IE <=8 the while (lastTimeoutId--) cycle may run over 8digits times and show the “A script on this page is causing Internet Explorer to run slowly” message. So if you can not save all you timeout id’s or don’t want to override window.setTimeout you may consider saving the first timeout id on a page and clearing timeouts until it.

Read More:   node dotenv won't work with pm2

Execute the code on early page load:

var clearAllTimeouts = (function () {
    var noop = function () {},
        firstId = window.setTimeout(noop, 0);
    return function () {
        var lastId = window.setTimeout(noop, 0);
        console.log('Removing', lastId - firstId, 'timeout handlers');
        while (firstId != lastId)
            window.clearTimeout(++firstId);
    };
});

And then clear all pending timeouts that probably was set by foreign code so many times you want

How about store the timeout ids in a global array, and define a method to delegate the function call to the window’s.

GLOBAL={
    timeouts : [],//global timeout id arrays
    setTimeout : function(code,number){
        this.timeouts.push(setTimeout(code,number));
    },
    clearAllTimeout :function(){
        for (var i=0; i<this.timeouts.length; i++) {
            window.clearTimeout(this.timeouts[i]); // clear all the timeouts
        }
        this.timeouts= [];//empty the id array
    }
};

You have to rewrite the window.setTimeout method and save its timeout ID.

const timeouts = [];
const originalTimeoutFn = window.setTimeout;

window.setTimeout = function(fun, delay) { //this is over-writing the original method
  const t = originalTimeoutFn(fn, delay);
  timeouts.push(t);
}

function clearTimeouts(){
  while(timeouts.length){
    clearTimeout(timeouts.pop());
  }
}

To clear all timeouts they must be “captured” first:

Place the below code before any other script and it will create a wrapper function for the original setTimeout & clearTimeout.

A new clearTimeouts methods will be added to the window Object, which will allow clearing all (pending) timeouts (Gist link).

Other answers lack complete support for possible arguments setTimeout might receive.

// isolated layer wrapper (for the local variables)
(function(_W){

var cache = [],                // will store all timeouts IDs
    _set = _W.setTimeout,      // save original reference
    _clear = _W.clearTimeout  // save original reference

// Wrap original setTimeout with a function 
_W.setTimeout = function( CB, duration, arg ){
    // also, wrap the callback, so the cache reference will be removed 
    // when the timeout has reached (fired the callback)
    var id = _set(function(){
        CB.apply(null, arguments)
        removeCacheItem(id)
    }, duration || 0, arg)

    cache.push( id ) // store reference in the cache array

    // id reference must be returned to be able to clear it 
    return id
}

// Wrap original clearTimeout with a function 
_W.clearTimeout = function( id ){
    _clear(id)
    removeCacheItem(id)
}

// Add a custom function named "clearTimeouts" to the "window" object
_W.clearTimeouts = function(){
    console.log("Clearing " + cache.length + " timeouts")
    cache.forEach(n => _clear(n))
    cache.length = []
}

// removes a specific id from the cache array 
function removeCacheItem( id ){
    var idx = cache.indexOf(id)

    if( idx > -1 )
        cache = cache.filter(n => n != id )
}

})(window);

For completeness, I wanted to post a general solution that covers both setTimeout and setInterval.

It seems browsers might use the same pool of IDs for both, but from some of the answers to Are clearTimeout and clearInterval the same?, it’s not clear whether it’s safe to rely on clearTimeout and clearInterval performing the same function or only working on their respective timer types.

Read More:   How to create Jest mock function with Promise?

Therefore, when the goal is to kill all timeouts and intervals, here’s an implementation that might be slightly more defensive across implementations when unable to test all of them:

function clearAll(windowObject) {
  var id = Math.max(
    windowObject.setInterval(noop, 1000),
    windowObject.setTimeout(noop, 1000)
  );

  while (id--) {
    windowObject.clearTimeout(id);
    windowObject.clearInterval(id);
  }

  function noop(){}
}

You can use it to clear all timers in the current window:

clearAll(window);

Or you can use it to clear all timers in an iframe:

clearAll(document.querySelector("iframe").contentWindow);

I use Vue with Typescript.

    private setTimeoutN;
    private setTimeoutS = [];

    public myTimeoutStart() {

        this.myTimeoutStop();//stop All my timeouts

        this.setTimeoutN = window.setTimeout( () => {
            console.log('setTimeout');
        }, 2000);

        this.setTimeoutS.push(this.setTimeoutN)//add THIS timeout ID in array

    }

    public myTimeoutStop() {

        if( this.setTimeoutS.length > 0 ) {
            for (let id in this.setTimeoutS) {
                console.log(this.setTimeoutS[id]);
                clearTimeout(this.setTimeoutS[id]);
            }
            this.setTimeoutS = [];//clear IDs array
        }
    }

Use a global timeout which all of your other functions derive timing from. This will make everything run faster, and be easier to manage, although it will add some abstraction to your code.

We’ve just published a package solving this exact issue.

npm install time-events-manager

With that, you can view all timeouts and intervals via timeoutCollection & intervalCollection objects.
There’s also a removeAll function which clears all timeouts/intervals both from the collection and the browser.

Inside the setTimeout after the definition of function f(…){} and timeout can be additional parameters.

For example: $setTimeout( function(a, b){ run(a); run(b); }, 100, a, b); )

…args solves that problem.

    var $timeouts = new Array();

    function $setTimeout(...args) 
    {
      var t = window.setTimeout(...args);
      $timeouts.push(t);
      return t;
    }

    function $clearTimeout(id) 
    {
        if( $timeouts.indexOf(id) > -1 )
            $timeouts = $timeouts.filter(n => n != id )

        window.clearTimeout(id);
    }


    function $clearTimeouts()
    {
        while($timeouts.length)
           window.clearTimeout($timeouts.pop());
    }

For old browsers you need to use another methods to pass parameters and to delete a value from the array $timeouts.

var $timeouts = new Array();

function $setTimeout() 
{
  var t = window.setTimeout.apply( this, arguments );
  $timeouts.push(t);
  return t;
}

function $clearTimeout(id) 
{
    var index = $timeouts.indexOf(id);

    if (index > -1) {
       $timeouts.splice(index, 1);
    }

    window.clearTimeout(id);
}


function $clearTimeouts()
{
    while($timeouts.length)
       window.clearTimeout($timeouts.pop());
}

The answers of the other are actually correct. But for me this is how approach this kind of stuff. Check my code bellow.


// example when I person types on search input
function typeOnSearch(time = 3000) {
  // this will clear timeout
  clearTimeout(window.typeOnSearchTimeOut); 

  // we create a timeout variable and added it to window, this way, we can access this in any function in our app.
  window.typeOnSearchTimeOut = setTimeout( () => {
    //enter what you like to do here, like fetch data
  }, time);
}


The answers/resolutions are collected from stackoverflow, are licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0 .

Similar Posts