Reputation: 54816
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.
Upvotes: 51
Views: 23697
Reputation: 46610
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.
Upvotes: 3
Reputation: 221
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.
Upvotes: 4
Reputation: 814
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?
Upvotes: 19
Reputation: 138082
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.
Upvotes: 8