Is there a way to clear all JavaScript timers at once?
Asked Answered
C

4

27

Im building an automatic refreshing comment section for my website using jQuery .load. So I am using a javascript 'setTimeout' timer to check for new comments.

But after doing some stuff like changing comment pages or deleting (all using ajax), a few old timers keep running, even though I used clearTimeout before loading new ajax content.

Is there some way to clear ALL javascript timers when I load new ajax content?

Cita answered 13/12, 2009 at 15:53 Comment(0)
L
31

There's no general function in javascript that allows you to clear all timers. You will need to keep track of all timers you create. For this you could use a global array:

var timers = [];
...
// add a timer to the array
timers.push(setTimeout(someFunc, 1000));
...
// clear all timers in the array
for (var i = 0; i < timers.length; i++)
{
    clearTimeout(timers[i]);
}
Liquidity answered 13/12, 2009 at 16:0 Comment(4)
The problem is that my newer loaded ajax content has no control over the old running timers.Cita
That's why I suggested a global variable.Liquidity
I've been struggling with this one. Brilliant! THanksDhar
while (id = timers.pop()) clearTimeout(id); <- I like this better, but makes little difference, the for loop is just as good, really - although I'm not allowed a var or let in front of the id declaration, which sucks - you could go with for(let id=timers.pop();id;id=timers.pop()) clearTimeout(id) instead, but then you lose the nicer lookRiyadh
O
44

Warning: My code bellow is problematic, mainly because the requirement is itself is problematic. I wonder why would you want to clear all timers any way. This makes your code breaking any plugin the uses the timers. Which is much more common than you may think, unless of course you're debugging or having fun, then it doesn't matter.


If you must:

This is one of the worst possible solutions. However it reveals a potential security vulnerability in JavaScript itself. But since it just works (clears ALL of the timers) I thought it would be cool to share it:

var maxId = setTimeout(function(){}, 0);

for(var i=0; i < maxId; i+=1) { 
    clearTimeout(i);
}
Overflow answered 12/1, 2012 at 9:0 Comment(13)
While the accepted answer is a cool best-practice, this answers the question posited in the title.Nosing
This is great solution! I guess it's cross-browser anyway?Roeder
@Roeder Based on my experience, I can say yes. But you should try it. Anyway it's very bad to this! Why would you want to do that!Overflow
@OmarIthawi As long as it works fine, it's not bad approach ;) Imagine there was in the JavaScript Standard function that do this same task. It would look exactly like the sample you gave.Roeder
I don't think there's anything in the standard stating that timer ids have to be incremented like that, so it's possible some browser may change it and cause that code to break. However, it's way more work to randomly generate id's and then keep track of them rather than just incrementing a counter.Borgerhout
@TimTisdall Oh, Yes! Programming is hard :) but it hopefully works on the 99.0% of the browsers in the market.Overflow
@OmarIthawi only that you leave yourself (or at least the user and the person maintaining your code at that time) screwed when in the future suddenly things change a whole lot, or a new browser appears and clears the plate within a short amount of time (as it happened again and again in browser history), which just happens to do it differently.Alberik
@Alberik I know! I've even mentioned it's bad!Overflow
you can do the same for requestAnimationFrame, just it requires cancelAnimationFrame and uses its own sequence if integer IDs.Blackberry
That was actually really useful for me. It can be helpful in debugging, when something goes out of control, but you don't want to reset the entire page.Blockbuster
@OmarIthawi you can use it for debugging. for instance stopping image sliders.Stieglitz
Huge code smell if you require something like this in your app, but I use it to avoid annoying modal ads. Works like a charm xDPylle
This assumes that timer IDs never get reused, if they ever do, this will failRiyadh
L
31

There's no general function in javascript that allows you to clear all timers. You will need to keep track of all timers you create. For this you could use a global array:

var timers = [];
...
// add a timer to the array
timers.push(setTimeout(someFunc, 1000));
...
// clear all timers in the array
for (var i = 0; i < timers.length; i++)
{
    clearTimeout(timers[i]);
}
Liquidity answered 13/12, 2009 at 16:0 Comment(4)
The problem is that my newer loaded ajax content has no control over the old running timers.Cita
That's why I suggested a global variable.Liquidity
I've been struggling with this one. Brilliant! THanksDhar
while (id = timers.pop()) clearTimeout(id); <- I like this better, but makes little difference, the for loop is just as good, really - although I'm not allowed a var or let in front of the id declaration, which sucks - you could go with for(let id=timers.pop();id;id=timers.pop()) clearTimeout(id) instead, but then you lose the nicer lookRiyadh
K
2

You may want to consider using jQuery Timers instead, which abstracts away many of the "ugly" details of setTimeout / setInterval, and makes them easier to use in your code for things like what you are describing.

Kappel answered 13/12, 2009 at 15:57 Comment(2)
@Benubird - Unfortunately that is the most recent one I can find. If you have a newer one, please let me know...Kappel
Yeah, looks like there is no current version (#3675066), might not be usable any more.Susa
S
1

This might help. I have a case that user is the one who is creating the timers, something like an open platform for development, obviously I don't have access to ID of those timers. So I need to sandbox them and remove them all if necessary. To do that I create a hidden <iframe> and load all timers in that iframe. To remove all timers, simply remove the iframe.

Suckling answered 16/8, 2018 at 7:24 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.