javascript - 取消揭示模块模式中失控的 JavaScript 超时/间隔

标签 javascript module instance settimeout setinterval

我有一个相当标准化的揭示模块模式来创建用作实例的对象。有时,在这些模式中,如果外部代码中不再使用或引用模块,则需要取消超时或间隔。

此模式的简化示例:

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/

相关文章:

javascript - 创建管理帐户而不在后端存储任何数据

javascript - 喜欢讨论Ember.js,有哪些大的开源项目写rails + angularjs?

javascript - 从 Electron 中的模块调用 main.js 中的对象

testing - 实时嵌入式系统模块测试

javascript - 有没有办法使用 EXPORT * 导出 ES6 模块中的所有名称?

object - '/' 应用程序中的服务器错误。你调用的对象是空的

javascript - fullcalendar 在本地主机中运行良好,但在服务器中运行不佳

ios - 可从 iOS 和 WatchKit Target 访问的单例框架 sharedInstance

JAVA 获取类中的实例名称?

javascript - 如何检查一个对象中的所有数字是否在某个范围内?