How to Stop All Timeouts and Intervals Using JavaScript

How to stop all timeouts and intervals using javascript?

Updated answer after reading the duplicate I closed this question with -

It works and tested in Chrome on OSX

// run somethingvar id1 = setInterval(function() { console.log("interval", new Date())}, 1000);var id2 = setTimeout(function()  { console.log("timeout 1", new Date())}, 2000);var id3 = setTimeout(function()  { console.log("timeout 2", new Date())}, 5000); // not run          setTimeout(function()  { console.log("timeout 3", new Date())}, 6000); // not run
// this will kill all intervals and timeouts too in 3 seconds. // Change 3000 to anything larger than 10
var killId = setTimeout(function() { for (var i = killId; i > 0; i--) clearInterval(i)}, 3000);
console.log(id1, id2, id3, killId); // the IDs set by the function I used

javascript: Clear all timeouts?

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
}

how to clear all javascript Timeouts?

__EDIT__

To manage a collection of timeouts (and intervals), you could use following snippet.
This will allow to clear any timeouts or intervals set anywhere in code, although, you have to set this snippet before setting any timeout or interval. Basically, before processing any javascript code or external script which uses timeout/interval.

JS:

;(function () {
window.timeouts = {},
window.intervals = {},
window.osetTimeout = window.setTimeout,
window.osetInterval = window.setInterval,
window.oclearTimeout = window.clearTimeout,
window.oclearInterval = window.clearInterval,
window.setTimeout = function () {
var args = _parseArgs('timeouts', arguments),
timeout = window.osetTimeout.apply(this, args.args);
window.timeouts[args.ns].push(timeout);
return timeout;
},
window.setInterval = function () {
var args = _parseArgs('intervals', arguments),
interval = window.osetInterval.apply(this, args.args);
window.intervals[args.ns].push(interval);
return interval;
},
window.clearTimeout = function () {
_removeTimer('timeouts', arguments);
},
window.clearInterval = function () {
_removeTimer('intervals', arguments);
},
window.clearAllTimeout = function () {
_clearAllTimer('timeouts', arguments[0]);
},
window.clearAllInterval = function () {
_clearAllTimer('intervals', arguments[0]);
};

function _parseArgs(type, args) {
var ns = typeof args[0] === "function" ? "no_ns" : args[0];
if (ns !== "no_ns")[].splice.call(args, 0, 1);
if (!window[type][ns]) window[type][ns] = [];
return {
ns: ns,
args: args
};
}

function _removeTimer(type, args) {
var fnToCall = type === "timeouts" ? "oclearTimeout" : "oclearInterval",
timerId = args[0];
window[fnToCall].apply(this, args);
for (var k in window[type]) {
for (var i = 0, z = window[type][k].length; i < z; i++) {
if (window[type][k][i] === timerId) {
window[type][k].splice(i, 1);
if (!window[type][k].length) delete window[type][k];
return;
}
}
}
}

function _clearAllTimer(type, ns) {
var timersToClear = ns ? window[type][ns] : (function () {
var timers = [];
for (var k in window[type]) {
timers = timers.concat(window[type][k]);
}
return timers;
}());
for (var i = 0, z = timersToClear.length; i < z; i++) {
_removeTimer(type, [timersToClear[i]]);
}
}
}());

How to use it:

Set timeout(s)/interval(s) as usual:

var test1 = setTimeout(function(){/**/, 1000);
var test2 = setTimeout(function(){/**/, 1000);

Then you could use to clear both:

clearAllTimeout(); // clearAllInterval(); for intervals

This will clear both timeouts (test1 & test2)

You can use some namespaces to clear only specific timers, e.g:

// first (optional) parameter for setTimeout/setInterval is namespace
var test1 = setTimeout('myNamespace', function(){/**/, 1000); // 'myNamespace' is current namespace used for test1 timeout
var test2 = setTimeout(function(){/**/, 1000); // no namespace used for test2 timeout

Again, clearAllTimeout(); will clear both timeouts. To clear only namespaced one, you can use:

clearAllTimeout('myNamespace'); // clearAllInterval('myNamespace'); for namespaced intervals

This will clear only test1 timeout

You could for some reason wish to delete non namespaced timeouts only. You could then use:

clearAllTimeout('no_ns'); // clearAllInterval('no_ns'); for non namespaced intervals only

This will clear only test2 timeout in this example

See jsFiddle DEMO

__END of EDIT__

Old post specific to opening question here:

You could try that:

var timeouts = [];

timeouts.push(setTimeout(function() {
social2();
}, 5000));

timeouts.push(setTimeout(function() {
social1();
}, 5000));

//etc...

function clearAllTimeouts(){
for(var i = 0, z = timeouts.length; i < z; i++)
clearTimeout(timeouts[i]);

timeouts = [];
}

UPDATED following David Thomas comment

var timeouts = {'social' : [], 'antisocial' : []};

//a social timeout
timeouts.social.push(setTimeout(function() {
social1();
}, 5000));

//an anti-social timeout
timeouts.antisocial.push(setTimeout(function() {
antisocial1();
}, 5000));

function clearTimeouts(namespace){
for(var i = 0, z = timeouts[namespace].length; i < z; i++)
clearTimeout(timeouts[namespace][i]);

timeouts[namespace] = [];
}

//usage e.g
clearTimeouts("social");

React hooks - right way to clear timeouts and intervals

Defined return () => { /*code/* } function inside useEffect runs every time useEffect runs (except first render on component mount) and on component unmount (if you don't display component any more).

This is a working way to use and clear timeouts or intervals:

Sandbox example.

import { useState, useEffect } from "react";

const delay = 5;

export default function App() {
const [show, setShow] = useState(false);

useEffect(
() => {
let timer1 = setTimeout(() => setShow(true), delay * 1000);

// this will clear Timeout
// when component unmount like in willComponentUnmount
// and show will not change to true
return () => {
clearTimeout(timer1);
};
},
// useEffect will run only one time with empty []
// if you pass a value to array,
// like this - [data]
// than clearTimeout will run every time
// this value changes (useEffect re-run)
[]
);

return show ? (
<div>show is true, {delay}seconds passed</div>
) : (
<div>show is false, wait {delay}seconds</div>
);
}

If you need to clear timeouts or intervals in another component:

Sandbox example.

import { useState, useEffect, useRef } from "react";

const delay = 1;

export default function App() {
const [counter, setCounter] = useState(0);
const timer = useRef(null); // we can save timer in useRef and pass it to child

useEffect(() => {
// useRef value stored in .current property
timer.current = setInterval(() => setCounter((v) => v + 1), delay * 1000);

// clear on component unmount
return () => {
clearInterval(timer.current);
};
}, []);

return (
<div>
<div>Interval is working, counter is: {counter}</div>
<Child counter={counter} currentTimer={timer.current} />
</div>
);
}

function Child({ counter, currentTimer }) {
// this will clearInterval in parent component after counter gets to 5
useEffect(() => {
if (counter < 5) return;

clearInterval(currentTimer);
}, [counter, currentTimer]);

return null;
}

Article from Dan Abramov.

How do I clear all intervals?

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.

Cancel all Javascript's setTimeouts and setIntervals

You need to keep the Id of each interval, timeout and requestAnimationFrame you've created and call window.clearInterval(id) etc. on them.

A verfy hackish/brute force way to do it would be something like:

for (var i = 1; i < 99999; i++) {
window.clearInterval(i);
window.clearTimeout(i);
window.mozCancelAnimationFrame(i); // Firefox
}

But I wouldn't recommend that.

Update:

To do it after a certain amount of time:

setTimeout(function () {
for (var i = 1; i < 99999; i++) {
window.clearInterval(i);
window.clearTimeout(i);
window.mozCancelAnimationFrame(i); // Firefox
}
}, 3000); // After 3 seconds

Update 2:

I don't believe there is a better way than the brute force way if you don't keep a reference for each time out etc, so to make it a bit easier to do that (as suggested by this SO answer), you could override the default setInterval:

var intervals = new Array();
window.oldSetInterval = window.setInterval;
window.setInterval = function(func, interval) {
intervals.push(oldSetInterval(func, interval));
}

// Now you can loop over intervals and clear them
// one by one when ever you want to.

for (var interval in intervals) {
window.clearInterval(interval);
}

The example shows how to do it for setInterval, but could of course be done the same way on setTimeout and requestAnimationFrame as well.

Viewing all the timeouts/intervals in 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.

Stop setInterval call in JavaScript

setInterval() returns an interval ID, which you can pass to clearInterval():

var refreshIntervalId = setInterval(fname, 10000);

/* later */
clearInterval(refreshIntervalId);

See the docs for setInterval() and clearInterval().



Related Topics



Leave a reply



Submit