For node.js
var timer = setInterval(function(){console.log('hi')},1000);
var notATimer = {};
var number = 2;
detectTimer(timer) //returns true
detectTimer(notATimer) //returns false
detectTimer(number) //returns false
Is there any way to reliably determine whether or not an object is an interval? Also, bonus points if the way to detect it also works for setTimeout.
For node.js
var timer = setInterval(function(){console.log('hi')},1000);
var notATimer = {};
var number = 2;
detectTimer(timer) //returns true
detectTimer(notATimer) //returns false
detectTimer(number) //returns false
Is there any way to reliably determine whether or not an object is an interval? Also, bonus points if the way to detect it also works for setTimeout.
Share Improve this question edited Apr 5, 2016 at 19:41 asked Apr 5, 2016 at 19:02 user773737user773737 8- 1 Why would you want to do that? – nyumerics Commented Apr 5, 2016 at 19:05
-
1
typeof timer
isnumber
andnotATimer
is anobject
. – Nonemoticoner Commented Apr 5, 2016 at 19:06 - @Nonemoticoner that won't suffice a generic setup. An edit was made though to explicitly mention that. – nyumerics Commented Apr 5, 2016 at 19:08
-
@Nonemoticoner:
typeof timer
is"object"
in node – Bergi Commented Apr 5, 2016 at 19:10 -
3
I'm not aware of anyway to do it - but one hack-ish way, add a property to setTimeout prototype
prototype.someProp = 'timer'
and then check for that, or better yet defer to @Neals answer – Foreign Object Commented Apr 5, 2016 at 19:14
4 Answers
Reset to default 11In nodejs, setTimeout
and setInterval
return Timeout
instances. That constructor is not exported, but you still can access it and use it to detect timer objects:
const Timeout = setTimeout(function(){}, 0).constructor;
function isTimer(t) { return t instanceof Timeout; }
If you don't want to do that, you can also use duck typing, by testing what properties the object has.
Both setTimeout
and setInterval
return an id reference (in the browser).
In node they return a reference to a Timeout
object.
So no, there is no real way to determine whether the returned value is from a timer, or just a variable from somewhere in the browser.
In node you can technically do an instanceof Timeout
check on the returned value's constructor, but personally I do not like doing that.
You can however wrap your timer implementation in some wrapping object caller which you can then check for which will work on node and on the client side.
For example:
class Timer {
constructor(callback, time) {
this.timeId = setTimeout(callback, time);
}
clear() {
clearTimeout(this.timeId);
}
}
const time = new Timer(() => console.log('hi'), 1000);
console.log(time instanceof Timer); // true
I don't think that's possible with regular methods as already mentioned by others. However, you could create a wrapper like
// Timeout, Interval, whatever
class Interval {
constructor(...args) {
this.interval = setInterval(...args); // again, whatever fits your needs
return this;
}
/* ... */
}
Which, applied, would be
const timer = new Interval(() => console.log('I am an interval'), 1000);
console.log(timer instanceof Interval) // => true (It's an interval)
Now that's just a basic example but I hope it gives you the right idea.
I would suggest changing the setTimeout and setInterval functions for javascript, I realized after the fact that you tagged this for node.js as well, so here's a javascript answer only, as the other answers handle node.js very well
window.originalSetTimeout=window.setTimeout;
window.originalClearTimeout=window.clearTimeout;
window.originalSetInterval=window.setInterval;
window.originalClearInterval=window.clearInterval;
window.setTimeout=function(func,delay)
{
ret=window.originalSetTimeout(func,delay);
ret +='-timeout';
return ret;
};
window.setInterval=function(func,delay)
{
ret=window.originalSetInterval(func,delay);
ret +='-interval';
return ret;
};
window.clearTimeout=function(timerID)
{
tid=timerID.split('-')[0];
window.originalClearTimeout(tid);
};
window.clearInterval=function(timerID)
{
tid=timerID.split('-')[0];
window.originalClearInterval(tid);
};
isTimeout=function(timerID)
{
t=timerID.split('-')[1];
if(t == "timeout") return true;
return false;
}
isInterval=function(timerID)
{
t=timerID.split('-')[1];
if(t == "interval") return true;
return false;
}
t=setTimeout(function(){console.log('here');},5000);
if(isTimeout(t)) document.getElementById('mess').innerHTML+='<BR>t is a Timeout';
if(isInterval(t)) document.getElementById('mess').innerHTML+='<BR>t is an Interval';
p=setInterval(function(){console.log('Interval here');},5000);
if(isTimeout(p)) document.getElementById('mess').innerHTML+='<BR>p is a Timeout';
if(isInterval(p)) document.getElementById('mess').innerHTML+='<BR>p is an Interval';
<div id="mess"></div>
.