So I was wondering, is there any feasible way in JavaScript to view information about scheduled timeouts and intervals that you don't explicitly know about (I know setTimeout
and setInterval
return a handle that can be used to refer to the scheduled instance, but say that this is unavailable for one reason or another)? For instance, is there a way to use a tool like Chrome's JavaScript console to determine what timeouts are currently active on an arbitrary page, when they will fire, and what code will be executed when they fire? More specifically, say a page has just executed the following JavaScript:
setTimeout("alert('test');", 30000);
Is there some code I can execute at this point that will tell me that the browser will execute alert('test');
30 seconds from now?
It seems like there theoretically should be some way to get this information since pretty much everything in JavaScript is exposed as a publicly accessible property if you know where to look, but I can't recall an instance of ever doing this myself or seeing it done by someone else.
The global clearTimeout() method cancels a timeout previously established by calling setTimeout() .
The setInterval method has the same syntax as setTimeout : let timerId = setInterval(func|code, [delay], [arg1], [arg2], ...) All arguments have the same meaning. But unlike setTimeout it runs the function not only once, but regularly after the given interval of time.
Even more concerning is the fact that it resumes from the same time it paused on, missing the time period in between. So, if we create any mission critical application in Javascript which uses timer, the result would be catastrophic. The reason why this happens is because Javascript is single threaded.
We all know that passing a string to setTimeout (or setInterval ) is evil, because it is run in the global scope, has performance issues, is potentially insecure if you're injecting any parameters, etc. So doing this is definitely deprecated: setTimeout('doSomething(someVar)', 10000);
how about simply rewriting the setTimeout function to sort of inject custom logging functionality?
like
var oldTimeout = setTimeout;
window.setTimeout = function(callback, timeout) {
console.log("timeout started");
return oldTimeout(function() {
console.log('timeout finished');
callback();
}, timeout);
}
might work?
No, even the HTML5 spec (which is a rationalisation of the HTML 4.01 behaviour in current browsers, with additional features) doesn't specify a way to list the available callbacks.
We've just published a package solving this exact issue.
npm install time-events-manager
With that, you can view them via timeoutCollection
& intervalCollection
objects.
You could also create a timer manager module which will keep track of current timers and allow you to get, add, stop and stop all timers.
var timers = (function() {
//
var timers = []
//
const getIndex = (array, attr, value) => {
for (let i = 0; i < array.length; i += 1) {
if (array[i][attr] === value) {
return i
}
}
return -1
};
// add
const add = (callback, time) => {
var id = setTimeout(() => {
let index = getIndex(timers, 'id', id)
timers.splice(index, 1)
callback()
}, time)
timers.push({
id: id,
time: time,
debug: callback.toString()
})
};
// get all active timers
const all = () => timers
// stop timer by timer id
const stop = (id) => {
if (!isNaN(id)) {
let index = getIndex(timers, 'id', id)
if (index !== -1) {
clearTimeout(timers[index].id)
timers.splice(index, 1)
}
}
};
// stop all timers
const stopAll = () => {
for (let i = 0; i < timers.length; i++) {
clearTimeout(timers[i].id)
}
timers = []
};
return {
add: add,
all: all,
stop: stop,
stopAll: stopAll,
};
})();
//
timers.add(function() {
console.log("timeout 1 fired");
}, 1000)
timers.add(function() {
console.log("timeout 2 wont get fired");
}, 2000)
timers.add(function() {
console.log("timeout 3 fired");
}, 3000)
timers.add(function() {
console.log("timeout 4 fired, timers", timers.all());
}, 4000)
timers.add(function() {
console.log("timeout 5 fired");
}, 5000)
console.log('All timers', timers.all())
console.log("kill timer 2")
timers.stop(2)
Run the snippet to see it in action.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With