最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How can I detect if an object is an intervaltimeout? - Stack Overflow

programmeradmin3浏览0评论

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 is number and notATimer is an object. – 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
 |  Show 3 more ments

4 Answers 4

Reset to default 11

In 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>

.

发布评论

评论列表(0)

  1. 暂无评论