使用setInterval与clearInterval踩的小坑总结

现场回顾

每次启动弹幕的时候会用setInterval产生一个定时器,每隔2秒产生一条新弹幕,一直循环。 当需要切换页面需要关闭页面时,使用clearInterval清理掉定时器,并且把已经产生的弹幕清空,简略代码如下:

let barrageTimer = null;
// 循环生成弹幕,每次调用生成一条弹幕
function barrageStart() {
  barrageTimer = setInterval(()=>{
    createBarrage();
  },2000);
} 

// 关闭弹幕,并清理已生成的弹幕
function barrageEnd() {
  clearInterval(barrageTimer);
  barrageList = [];  
}

// 小程序页面每次载入时调用
onShow() {
  barrageStart();
}
// 小程序页面隐藏或切换后台时调用
onHide() {
  barrageEnd();
}

复制代码

当我写完这段代码时,自信满满,觉得运行起来一定没问题,结果呢...... 页面里的弹幕定时器还在欢快地跑着,丝毫没有收到clearInterval的影响...... 可以说是很气人了,但是还是要保持微笑...

问题总结

查询MDN后,明确setInterval被执行后其实会返回一个定时器的id,每生成一个定时器都会返回其id,相当于每次进入页面的时候,都产生了一个定时器,当页面快速切换的时候,有可能clearInterval还没有把本次页面产生的定时器清除,barrageTimer又被新的定时器id给覆盖了,造成总有定时器在跑的结果。 想要解决这个问题也很简单,在产生新的定时器前,检查下,只要有旧的定时器id,再停止一次,防止定时器id相互覆盖即可。

function barrageStart() {
  if (barrageTimer) {
    clearInterval(barrageTimer);
  }
  barrageTimer = setInterval(()=>{
    createBarrage();
  },2000);
} 

function barrageEnd() {
  clearInterval(barrageTimer);
  barrageTimer = 0;
  barrageList = [];  
}
复制代码

当然这还不够,最好是能用一个数组将定时器id直接存进去,需要清理的时候统一清理

let barrageTimer = null;
let barrageTimerList = []
function barrageStart() {
  barrageTimer = setInterval(()=>{
    createBarrage();
  },2000);
  barrageTimerList.push(barrageTimer)
} 

function barrageEnd() {
  barrageTimerList.forEach((item,index)=>{
    clearInterval(item)
  })
  barrageTimerList = []
  barrageTimer = 0;
  barrageList = [];  
}
复制代码
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值