18

Does the browser keep track of active setInterval and setTimeout IDs? Or is this solely up to the developer to keep track of?

If it does keep track of them, is it accessible via the BOM?

Yi Jiang
  • 49,435
  • 16
  • 136
  • 136
ground5hark
  • 4,464
  • 8
  • 30
  • 35
  • 2
    I would like to see a good answer to this too; I think it's "no" but I've never really researched it. – Pointy May 11 '10 at 22:41
  • 1
    Well even if it did somehow register them, how would you know which is which? Well I guess if you know there's just one timeout or interval or whatever, you wouldn't need to know. – Pointy May 11 '10 at 23:16
  • Haha, you said "BOM" instead of DOM. – Felix May 12 '10 at 10:41
  • 2
    @Felix I think he meant it. BOM = "Browser Object Model" as in the `window`, `navigator`, `opener` type objects – scunliffe May 12 '10 at 14:04
  • "You said 'boehm'" - no wait, that was the Pink Panther ;) – FruitBreak Jan 18 '13 at 17:50

5 Answers5

4

You can add such global timers tracking by overriding the setTimeout/seInterval functions. As a bonus you easily add code when a timer is set or popped, track live timers or popped timers, etc...

For example:

timers = {}; // pending timers will be in this variable
originalSetTimeout = window.setTimeout;
// override `setTimeout` with a function that keeps track of all timers
window.setTimeout = function(fu, t) {
    var id = originalSetTimeout(function() {
        console.log(id+" has timed out");
        delete timers[id]; // do not track popped timers 
        fu();
    }, t);
    // track this timer in the `timers` variable
    timers[id] = {id:id,  setAt: new Date(),  timeout: t};
    console.log(id+" has been set to pop in "+t+"ms");
}
// from this point onward all uses of setTimeout will be tracked, logged to console and pending timers will be kept in the global variable "timers".
Iftah
  • 9,512
  • 2
  • 33
  • 45
4

It is up for the developer to keep track of. You can do so by using the returned value of the setTimeout/setInterval function and passing that value to the clearTimeout/clearInterval function - as described in other answers here.

This appears to be because each browser will implement keeping track of the intervals in their own way.

From w3.org/TR/2009/WD-html5-20090212/no.html (a draft, but w3schools and http://w3.org/TR/Window explain it almost the same way) - setTimeout and setInterval return a long and clearTimeout/clearInterval accept a long to find and cancel

s_hewitt
  • 4,252
  • 24
  • 24
1

This may interest you, if you are curious about how the timer is 'remembered' by its window.

<!doctype html> 
<html lang= "en"> 
<head> 
<meta charset= "utf-8"> 
<title>Timer </title> 
</head> 
<body>
<h1>Timers</h1>
<script>

if(!window.timers){
    var timers= [], i= 0;
    while(i<5){
        timers.push(setInterval(function(){
            if(confirm(timers.join('\n')+'\nRemove a timer?')){
                clearInterval(timers.shift());
            }
        },
        i*1000+1000));
        ++i;
    }
}
</script>

</body> 
</html> 
kennebec
  • 102,654
  • 32
  • 106
  • 127
0

Update:

There are 2 aspects to this question.

  1. Does the browser keep track of timer IDs?
  2. Are they accessible

I can only presume for #1 (and later #2) that the OP means "are they tracked" in the general sense because as a Developer s/he would like control over them.

In short, yes they are tracked (as @s_hewitt noted, as long values by the browser) and they can be managed by the developer by maintaining a reference to the timers when setup.

As a developer you can control (e.g. stop) them by calling (clearInterval(handleRef), or clearTimeout(handleRef))

However there is no default window.timers or similar collection that gives you a list of the existing timers - you will need to maintain that yourself if you feel you need to.

function startPolling(delay){
  pollHandle = setInterval(doThis, delay);
}
function stopPolling(){
  clearInterval(pollHandle);
}

function doThisIn30minUnlessStopped(){
  timerHandle = setTimeout(doThisThing, 1800000);
}
function stop30minTimer(){
  clearTimeout(timerHandle);
}    

You simply need to create a variable reference to your timer, and if/when needed, clear it by name.

When you load another page, all the timers are automatically cleared by the browser so you don't need to maintain a handle, and clear them unless you need/want to.

scunliffe
  • 62,582
  • 25
  • 126
  • 161
  • 2
    This works, but I pass the object "clearTimeout(timerHandle)" instead of name of the object "clearTimeout('timerHandle')". Haven't investigated which is the preferred method. – s_hewitt May 11 '10 at 23:25
  • @s_hewitt - yeah both work. In a more complex example I usually create the timer as an expando property on some object to keep it out of the global scope, and then remove it calling it with a variable reference instead of a string – scunliffe May 11 '10 at 23:38
  • 3
    From http://www.w3.org/TR/2009/WD-html5-20090212/no.html (yes, its a draft, but w3schools and http://www.w3.org/TR/Window/ explain it almost the same way) - setTimeout and setInterval return a long and clearTimeout/clearInterval accept a long to find and cancel. – s_hewitt May 11 '10 at 23:46
  • 3
    More to the OP's question - I couldn't find anything that gives access to the internal list of active timeouts / intervals or describes how to store them. I assume this is because each browser will implement it in their own way. – s_hewitt May 11 '10 at 23:46
  • @s_hewitt correct, you need to pass the number, not the string. I've tested the code example above, and it fails in IE8 and Firefox. Perhaps it worked in an old version of IE. Here is the code that does not work: http://pastebin.com/ntkrX113 Remove the quotes around 'pollHandle' and then it is fine. – Douglas May 12 '10 at 11:42
  • I'll have to take a look at this later, but I'm 500% positive it works (unless I've made a glaring typo)... – scunliffe May 12 '10 at 12:12
0

Look at the scripts below, the browser could remember the id of each setTimeout iteration

for (i = 1; i <= d; i++) {
          (function(j) {
                var delay = j/d; 
               t[j] = setTimeout(function() {      
                      elem.style.top = j+"px";
                     },delay);

            })(i);           
 } 

You can access them by

for (i in t) {
      alert(t[i]);  
 }
unigg
  • 466
  • 3
  • 8