Javascript 如何检测对象是否为间隔/超时?
对于node.jsJavascript 如何检测对象是否为间隔/超时?,javascript,node.js,Javascript,Node.js,对于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 是否有任何方法可以可靠地确定对象是否为间隔? 此外,如果检测设置
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
和setInterval
返回一个id引用(在浏览器中)
在节点中,它们返回对超时
对象的引用
因此,没有真正的方法来确定返回值是来自计时器,还是来自浏览器中某个地方的变量
在节点中技术上可以对返回值的构造函数执行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
在nodejs和return实例中。该构造函数未导出,但您仍然可以访问它并使用它检测计时器对象:
const Timeout = setTimeout(function(){}, 0).constructor;
function isTimer(t) { return t instanceof Timeout; }
如果您不想这样做,您也可以通过测试对象的属性来使用duck类型。我认为其他人已经提到的常规方法不可能做到这一点。但是,您可以创建一个包装器,如
// 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=函数(func,延迟)
{
ret=窗口原始设置超时(func,延迟);
ret+='-超时';
返回ret;
};
window.setInterval=函数(func,delay)
{
ret=窗口原始设置间隔(func,延迟);
ret+='-间隔';
返回ret;
};
window.clearTimeout=函数(timerID)
{
tid=timerID.split('-')[0];
窗口原始清除超时(tid);
};
window.clearInterval=函数(timerID)
{
tid=timerID.split('-')[0];
窗口原始清除间隔(tid);
};
isTimeout=函数(timerID)
{
t=timerID.split('-')[1];
if(t==“timeout”)返回true;
返回false;
}
isInterval=函数(timerID)
{
t=timerID.split('-')[1];
如果(t==“间隔”)返回true;
返回false;
}
t=setTimeout(函数(){console.log('here');},5000);
if(isTimeout(t))document.getElementById('mess').innerHTML+='
t是超时';
if(isInterval(t))document.getElementById('mess').innerHTML+='
t是一个区间';
p=setInterval(函数(){console.log('Interval here');},5000);
if(isTimeout(p))document.getElementById('mess').innerHTML+='
p是一个超时';
if(isInterval(p))document.getElementById('mess').innerHTML+='
p是一个区间';
为什么要这样做?定时器的类型是数字
,notATimer
是一个对象
@Nonemoticoner,不能满足一般设置。尽管进行了一次编辑,明确提到了这一点。@Nonemoticoner:typeof timer
是node中的“object”
,我不知道该怎么做-但有一种黑客方法,将一个属性添加到setTimeout prototypeprototype.someProp='timer'
,然后检查它,或者更好的做法是听从@Neals answer这个问题是关于node的,而不是DOM api。答案的第一段暗示了这一点,因为node没有为计时器返回整数引用。setInterval
与DOM api有什么关系setInterval
返回一个number
,这是通过clearInterval()取消时使用的id
DOM API返回一个整数,标识计时器。CommonJSAPI(相同调用)返回一个计时器对象。如果您在浏览器中运行,这是正确的解决方案。@ndugger:很抱歉我的公式太草率了。它应该是“这个问题是关于在NodeJS环境中执行的代码,而不是在具有的DOM环境中执行的代码”。虽然包装器对象可以很好地解决OP面临的问题,但在我看来,这个答案(“否”)并不能真正回答这个问题-P在我看来很好,但这与我的答案是一样的。是的,我也注意到了,但我向你保证,我没有模仿你:PI很高兴我最终能给出答案,但有你^^很乐意帮助。。。我认为?@Neal:)我的答案在节点端和客户端都有效。在我看来,访问对象的构造函数也是“讨厌的”。@Neal:当然,客户端需要一个包装器(这是一个很好的解决方案!),但这不是OP要求的。还有一点是正确的,Timeout
没有导出是有充分的理由的,解决这些问题可能会给您带来麻烦,但这是唯一真正可靠的方法。在节点v11.5.0上不起作用:“ReferenceError:Timeout未定义”@ekkis-Hm,我现在无法尝试,请使用调试器检查setTimeout
的返回值好吗?NodeJSIDN中没有窗口
,我不知道这是针对node的。@GregBorbonus这几乎不清楚。问题中没有明确提及,只是通过标签间接提及,这通常是垃圾邮件和不可靠的。谢谢勒克斯,我编辑了答案以表明这是一个错误。我以前从未想过这是一个问题,但我非常喜欢这个解决方案,最终我会自己使用它。