关于需要大量定义销毁定时器环境的保险优化策略

80 阅读1分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第22天

关于需要大量定义销毁定时器环境的保险优化策略

问题发生在封装轮播图组件时,因为需要配合用户点击、滑动以及切换路由等操作,定时器也需要不停地进行定义与销毁,起先我在data域中定义了timer用来接收创建的定时器id,提供给未来销毁时使用:

setTimer(){
            this.timer = window.setInterval(()=>{
                document.getElementById('scrollShell').setAttribute('class','transitionStyle');
                this.next();
                console.log(this.timers.length);
            }
            ,3000)
    //通过$once监听来使timer在组件销毁前失效
            this.$once('hook:beforeDestroy', () => {
                window.clearInterval(timer);
            })
        },
            
clearTimer(){
                window.clearInterval(this.timer);
​
        }

但这时候出现了问题,运行时间过长时,或点击次数足够多时,页面中会同时出现数个定时器,使图片轮播加速,通过各方调试,均未找到哪里处理有误,只好另辟蹊径,从清除定时器方面下手

方案一:

如果我们观察timer的话,会发现它是有序排列的Number数据,会从1开始,往后的计时器就定义为2,3,4...

于是我通过暴力法来清除定时器

for(let i = 0;i < 1000;i++){
    window.clearInterval(i)
}

但这样处理明显有缺陷,先不说循环占用的资源,单是定时器的id也在不断增加,如果在一个页面停留时间足够长,其id迟早会超过你定义的清除范围,于是我有了方案二

方案二:

不管为什么定时器没有被及时清除掉,它的源头总来自我们的定义,所以我将data域中timer改为了数组,每当新建了一个定时器,就在数组后push其id,每当清除了定时器,就在数组后将其pop掉,很方便的是,我们也可以通过timer的长度来判断全局中定时器的数量,达到及时清理的效果

setTimer(){
            let timer = window.setInterval(()=>{
                document.getElementById('scrollShell').setAttribute('class','transitionStyle');
                this.next();
                console.log(this.timers.length);
            }
            ,3000)
            this.timers.push(timer)
            //通过$once监听来使timer失效
            this.$once('hook:beforeDestroy', () => {
                window.clearInterval(timer);
            })
        },
        clearTimer(){
            for(let timer of this.timers){
                console.log(timer);
                console.log(this.timers);
                window.clearInterval(timer);
            }
            this.timers = [];
        }