如何检测对象是否为间隔/超时

How can I detect if an object is an interval/timeout?

本文关键字:超时 是否 对象 何检测 检测      更新时间:2024-01-06

对于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

有没有什么方法可以可靠地确定一个对象是否是一个区间?此外,如果检测它的方法也适用于setTimeout,则可获得加分。

在nodejs中,setTimeoutsetInterval返回Timeout实例。该构造函数没有导出,但您仍然可以访问它并使用它来检测计时器对象:

const Timeout = setTimeout(function(){}, 0).constructor;
function isTimer(t) { return t instanceof Timeout; }

如果您不想这样做,还可以通过测试对象的属性来使用duck类型。

setTimeoutsetInterval都返回一个id引用(在浏览器中)。

在节点中,它们返回对Timeout对象的引用。

因此no,没有真正的方法来确定返回值是来自计时器,还是只是来自浏览器中某个地方的变量。

节点中,技术上可以对返回值的构造函数执行instanceof Timeout检查,但我个人不喜欢这样做。


但是,可以将计时器实现封装在某个封装对象调用程序中,然后您可以检查哪个将在客户端的节点上工作。

例如:

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

我认为其他人已经提到的常规方法不可能做到这一点。但是,您可以创建一个类似的包装器

// Timeout, Interval, whatever
class Interval {
    constructor(...args) {
        this.interval = setInterval(...args); // again, whatever fits your needs
        return this;
    }
    /* ... */
}

如果适用,将是

const timer = new Interval(() => console.log('I am an interval'), 1000);
console.log(timer instanceof Interval) // => true (It's an interval)

这只是一个基本的例子,但我希望它能给你正确的想法。

我建议更改javascript的setTimeout和setInterval函数,在您为node.js标记了这两个函数之后,我意识到了这一点,所以这里只有一个javascript答案,因为其他答案可以很好地处理node.js

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>