动态改变setInterval的时间间隔

2020-12-24  本文已影响0人  leptune

因为js自带的setInterval是无法修改时间间隔,所以根据setInterval的参数做了个完全兼容setInterval的插件(除了不支持代码字符串之外)。

插件特性:

具体使用方法见代码:



(function () {
    var intervals = [];
    var current_id = 1;

    // 清除计时器:uid为set_interval返回的计时器ID
    window.clear_interval = function(uid) {
        if (!intervals[uid]) {
            return;
        }
        intervals[uid].need_stop = true;
    };

    // 清除所有计时器
    window.clear_all_intervals = function() {
        for (var uid in intervals) {
            clear_interval(uid);
        }
    };

    // 获取所有计时器的ID
    window.get_intervals = function() {
        var all_ids = [];
        for (var i = 1; i < intervals.length; i++) {
            if (!intervals[i].need_stop) {
                all_ids.push(i);
            }
        }
        return all_ids;
    };

    // 获取对应计时器的时间间隔(返回毫秒数):uid为set_interval返回的计时器ID
    window.get_interval_time = function(uid) {
        if (!intervals[uid]) {
            return;
        }
        return intervals[uid].time;
    };

    // 获取对应计时器的额外参数(返回数组):uid为set_interval返回的计时器ID
    window.get_interval_args = function(uid) {
        if (!intervals[uid]) {
            return;
        }
        return intervals[uid].extra_args;
    };

    // 获取对应计时器的执行函数(返回匿名函数):uid为set_interval返回的计时器ID
    window.get_interval_fn = function(uid) {
        if (!intervals[uid]) {
            return;
        }
        return intervals[uid].fn;
    };

    // 更改对应计时器的间隔时间:uid为set_interval返回的计时器ID,time为要修改的时间间隔(单位毫秒)
    window.change_interval_time = function(uid, time) {
        if (!intervals[uid]) {
            return;
        }
        intervals[uid].time = time;
    };

    // 更改对应计时器的额外参数:uid为set_interval返回的计时器ID,extra_args为要修改的额外参数(必须是数组)
    window.change_interval_args = function(uid, extra_args) {
        if (!intervals[uid]) {
            return;
        }
        intervals[uid].extra_args = extra_args;
    };

    // 更改对应计时器的执行函数:uid为set_interval返回的计时器ID,fn为要修改的执行函数(函数名或者匿名函数)
    window.change_interval_fn = function(uid, fn) {
        if (!intervals[uid]) {
            return;
        }
        intervals[uid].fn = fn;
    };
        
    // 开始计时器:参数为:要执行的函数、时间间隔(单位毫秒)、[额外参数1, 额外参数2, ...]
    // 注意:调用后,会先立即执行要执行的函数,然后每隔指定的时间间隔,就会再次调用。
    window.set_interval = function() {
        if (arguments.length < 2 || typeof arguments[0] != 'function') {
            return;
        }
        var uid = current_id++;
        intervals[uid] = {
            fn: arguments[0],
            time: parseInt(arguments[1]),
            need_stop: 0,
            extra_args: [],
            interval_func: function(uid) {
                if (!intervals[uid] || intervals[uid].need_stop) {
                    return;
                }
                intervals[uid].fn.apply(null, intervals[uid].extra_args); // 传入调用者自定义的参数
                setTimeout(intervals[uid].interval_func, intervals[uid].time, uid);
            },
        };
        for (var i=2; i<arguments.length; i++) {
            intervals[uid].extra_args.push(arguments[i]);
        }
        intervals[uid].interval_func(uid);
        return uid;
    };
})();

// 使用示例
var start = +new Date();
var uid = set_interval(function(arg1, arg2) {
    console.log(+new Date() - start, arg1, arg2)
}, 1000, 'extra_arg1', 'extra_arg2');

change_interval_time(uid, 2000); // 改为每2秒执行1次

// 改变要执行的函数
change_interval_fn(uid, function() {
    console.log(11);
});

// 改变额外参数
change_interval_args(uid, ['change_arg1', 2, 3,'end']);

clear_interval(uid); // 清除该interval

clear_all_intervals(); // 清除所有interval

上一篇下一篇

猜你喜欢

热点阅读