持续创作,加速成长!这是我参与「掘金日新计划 · 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 = [];
}