Viewing all the timeouts/intervals in javascript?

JavascriptTimeoutSetinterval

Javascript Problem Overview


I'm writing an application that utilizes JavaScript timeouts and intervals to update the page. Is there a way to see how many intervals are setup? I want to make sure that I'm not accidentally going to kill the browser by having hundreds of intervals setup.

Is this even an issue?

Javascript Solutions


Solution 1 - Javascript

I don't think there is a way to enumerate active timers, but you could override window.setTimeout and window.clearTimeout and replace them with your own implementations which do some tracking and then call the originals.

window.originalSetTimeout = window.setTimeout;
window.originalClearTimeout = window.clearTimeout;
window.activeTimers = 0;

window.setTimeout = function(func, delay) {
	window.activeTimers++;
	return window.originalSetTimeout(func, delay);
};

window.clearTimeout = function(timerID) {
	window.activeTimers--;
	window.originalClearTimeout(timerID);
};

Of course, you might not always call clearTimeout, but this would at least give you some way to track what is happening at runtime.

Solution 2 - Javascript

I made a Chrome DevTools extension that shows all intervals. Cleared ones are greyed out.

Timers Chrome Devtool extension

setInterval-sniffer

Solution 3 - Javascript

Instead of just have a count of timers, here is an implementation which stores all timerid's into an array. It only shows active timers while the accepted answer only counts calls to setTimeout & clearTimeout.

(function(w) {
    var oldST = w.setTimeout;
    var oldSI = w.setInterval;
    var oldCI = w.clearInterval;
    var timers = [];
    w.timers = timers;
    w.setTimeout = function(fn, delay) {
        var id = oldST(function() {
            fn && fn();
            removeTimer(id);
        }, delay);
        timers.push(id);
        return id;
    };
    w.setInterval = function(fn, delay) {
        var id = oldSI(fn, delay);
        timers.push(id);
        return id;
    };
    w.clearInterval = function(id) {
        oldCI(id);
        removeTimer(id);
    };
    w.clearTimeout = w.clearInterval;

    function removeTimer(id) {
        var index = timers.indexOf(id);
        if (index >= 0)
            timers.splice(index, 1);
    }
}(window));

This is how you can get the count of active timers on the page:

timers.length;

This is how you can remove all active timers:

for(var i = timers.length; i--;)
    clearInterval(timers[i]);
	

Known limitations:

  • You can only pass a function (not a string) to setTimeout with this monkey patch.
  • The function assumes clearInterval and clearTimeout do the same, which they do but it could change in the future.

Solution 4 - Javascript

Seeing as Paul has only covered setTimeout I thought I would share a counter for setInterval/clearInterval.

window.originalSetInterval = window.setInterval;
window.originalClearInterval = window.clearInterval;
window.activeIntervals = 0;
window.setInterval = function (func, delay)
{
	if(func && delay){
			window.activeIntervals++;
	}
	return window.originalSetInterval(func,delay);
};
window.clearInterval = function (intervalId)
{
	// JQuery sometimes hands in true which doesn't count
	if(intervalId !== true){
		window.activeIntervals--;
	}
	return window.originalClearInterval(intervalId);
};

Solution 5 - Javascript

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

npm install time-events-manager

With that, you can view and manage them via timeoutCollection object (and javascript's intervals viaintervalCollection object).

timeoutCollection.getScheduled(); timeoutCollection.getCompleted(); timeoutCollection.getAll();

Solution 6 - Javascript

I just needed something like this and this is what I've put together:

window.setInterval = function (window, setInterval) {
  if (!window.timers) {
    window.timers = {};
  }
  if (!window.timers.intervals) {
    window.timers.intervals = {};
  }
  if (!window.timers.intervals.active) {
    window.timers.intervals.active = {};
  }
  return function (func, interval) {
    var id = setInterval(func, interval);
    window.timers.intervals.active[id] = func;
    return id;
  }
}(window, window.setInterval);

window.clearInterval = function (window, clearInterval) {
  if (!window.timers) {
    window.timers = {};
  }
  if (!window.timers.intervals) {
    window.timers.intervals = {};
  }
  if (!window.timers.intervals.inactive) {
    window.timers.intervals.inactive = {};
  }
  return function (id) {
    if (window.timers.intervals.active && window.timers.intervals.active[id]) {
      window.timers.intervals.inactive[id] = window.timers.intervals.active[id];
      clearInterval(id);
      delete window.timers.intervals.active[id];
    }
  }
}(window, window.clearInterval);

This records the interval ids along with their functions, and also keeps track of their status (active/inactive).

Solution 7 - Javascript

Based on @Alessio's answer. Below is my version. Has a bit more functionality for logging and inspection.

Here is some boilerplate that you can alter to utilize your own frameworks:

var s$ = function (s){return new String(s)}
var _w=window
_w.q$ = {
  getMachineTimeMS: function(){
      var d = new Date(), ms = d.getMilliseconds()
      var a = [d.getHours(), d.getMinutes(), d.getSeconds(), '-', ms<10?'00' + s$(ms):ms<100?'0'+s$(ms):ms]
      return a.join('')
  }
  ,getCaller: function(opts){
      return "(implement this)"
  }
}

Here is the main code:

_w.setTimeout = function (orig_setTimeout) {
  var t=(_w._Timers = _w._Timers||{})
  var d=(t.Timeouts = t.Timeouts||{})
  d.Active = d.Active||{}
  t.z_to_id_idx = t.z_to_id_idx||{}
  return function (h, n) {
    var t = _w._Timers, d = t.Timeouts
    var id = orig_setTimeout(h, n), ts = q$.getMachineTimeMS()
    var c = q$.getCaller({depth:2})
    t.z_to_id_idx[s$(id)] = d.Active[ts] = {sts: ts, id: id, h: h, n: n, scaller: c}
    return id;
  }
}(_w.setTimeout);

_w.clearTimeout = function (orig_clearTimeout) {
  var t=_w._Timers, d = t.Timeouts
  d.Inactive = d.Inactive||{}
  return function new_clearTimeout(id) {
    var t = _w._Timers, d = t.Timeouts, sId = s$(id)
    if (!d.Active || !sId in t.z_to_id_idx) return
    var r = t.z_to_id_idx[sId]
    r.ccaller = q$.getCaller({depth:2})
    r.cts = q$.getMachineTimeMS()
    d.Inactive[r.ts] = r;
    orig_clearTimeout(r.id);
    delete d.Active[r.ts]
    delete t.z_to_id_idx[sId]
  }
}(_w.clearTimeout);

_w.setInterval = function (orig_setInterval) {
  var t=(_w._Timers = _w._Timers||{})
  var d=(t.Intervals = t.Intervals||{})
  d.Active = d.Active||{}
  t.z_in_id_idx = t.z_in_id_idx||{}
  return function (h, n) {
    var t = _w._Timers, d = t.Intervals
    var id = orig_setInterval(h, n), ts = q$.getMachineTimeMS()
    var c = q$.getCaller({depth:2})
    t.z_in_id_idx[s$(id)] = d.Active[ts] = {sts: ts, id: id, h: h, n: n, scaller: c}
    return id;
  }
}(_w.setInterval);

_w.clearInterval = function (orig_clearInterval) {
  var t=_w._Timers, d = t.Intervals
  d.Inactive = d.Inactive||{}
  return function new_clearInterval(id) {
    var t = _w._Timers, d = t.Intervals, sId = s$(id)
    if (!d.Active || !sId in t.z_in_id_idx) return
    var r = t.z_in_id_idx[sId]
    r.ccaller = q$.getCaller({depth:2})
    r.cts = q$.getMachineTimeMS()
    d.Inactive[r.ts] = r;
    orig_clearInterval(r.id);
    delete d.Active[r.ts]
    delete t.z_in_id_idx[sId]
  }
}(_w.clearInterval);

Usage example:

id = setTimeout(()=>{console.log("CALLED")}, 10000)
clearTimeout(id)
setInterval(()=>{console.log("CALLED")}, 1000)

console.table(_w._Timers.Timeouts.Inactive)

The console.table will output a nicely formatted and inspectable table in the JavaScript Console

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionOmar KoohejiView Question on Stackoverflow
Solution 1 - JavascriptPaul DixonView Answer on Stackoverflow
Solution 2 - JavascriptNVIView Answer on Stackoverflow
Solution 3 - JavascriptA1rPunView Answer on Stackoverflow
Solution 4 - JavascriptcrvView Answer on Stackoverflow
Solution 5 - JavascriptZiv polackView Answer on Stackoverflow
Solution 6 - JavascriptakinuriView Answer on Stackoverflow
Solution 7 - JavascriptTimothy C. QuinnView Answer on Stackoverflow