我有一个相当标准化的揭示模块模式来创建用作实例的对象。有时,在这些模式中,如果外部代码中不再使用或引用模块,则需要取消超时或间隔。
此模式的简化示例:
function test() {
window.timer = maketimer();
}
function maketimer() {
var cls, my;
my = {
increment: 0,
timerid: null,
exec_timer: function() {
my.timerid = window.setInterval(my.time, 2000);
},
time: function() {
console.log("timer: ", my.timerid, my.increment++);
}
},
cls = {
//...
}
my.exec_timer();
return cls;
};
test();
// some time later...
test();
如果 test
被调用两次,无论出于何种原因,变量 window.timer
都会被替换为 maketimer
的第二个实例但第一个实例计时器继续运行。
很多时候,我的模块本质上链接到 DOM 节点,并且 DOM 节点通常会与旧实例一起删除,因此理论上我可以检查该节点是否不存在或其位置在 DOM 之外,然后在这种情况下取消间隔。
然而,这是更通用的,我希望能够处理 DOM 环境之外的超时。
最佳答案
在这种情况下,我会将整个函数包装在 IIFE 中包含一个实例
变量。您可以在其中保存计时器。每启动一个新的,旧的就会被销毁:
(function(window) {
var timerInstance = null;
window.maketimer = function() {
var cls, my;
if(timerInstance) {
timerInstance.destroyInstance();
}
my = {
increment: 0,
timerid: null,
exec_timer: function() {
my.timerid = window.setInterval(my.time, 2000);
},
time: function() {
console.log("timer: ", my.timerid, my.increment++);
},
destroyInstance: function() {
window.clearInterval(my.timerid);
}
},
cls = {
//...
}
my.exec_timer();
timerInstance = my;
return cls;
}
})(window);
function test() {
window.timer = maketimer();
}
test();
test();
出于好奇,为什么需要将实例放在全局变量上? window.timer
非常通用,可以被其他脚本覆盖。
关于javascript - 取消揭示模块模式中失控的 JavaScript 超时/间隔,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33344326/