首页 > 技术文章 > Javascript 定时器

OrochiZ- 2020-05-10 14:51 原文

1.基本用法

Javascript定时器分为循环定时器和延时定时器

<script>
    //循环定时器 每秒输出当前的秒数
    setInterval(() => {
        console.log('当前秒数='+new Date().getSeconds())
    }, 1000)

    //延时定时器 3秒后输出
    setTimeout(() => {
        console.log('此字段由延时定时器打印')
    }, 3000);

</script>

2.清除定时器

  • 1.定时器创建时会返回一个id(通常是一个整数),可以利用这个id来清除此定时器
  • 2.clearInterval(id)和clearTimeout(id)分别用来清除循环定时器和延时定时器。
  • 3.定时器每次创建都会是一个新的定时器,所以创建前记得将前面创建的清除
<script>
    //用来记录定时器的id
    var timer = null
    //事件绑定
    document.querySelector('#begin').onclick = function(){
        timer = setInterval(() => {
            console.log('当前秒数='+new Date().getSeconds())
        }, 1000)
        console.log('此循环定时器id='+timer)
    }
    document.querySelector('#over').onclick = function(){
        //利用之前保存的timer清除循环定时器
        clearInterval(timer)
        console.log('清除此循环定时器')
    }
</script>

<script>
    //用来记录定时器的id
    var timer = null
    //事件绑定
    document.querySelector('#begin').onclick = function(){
        timer = setTimeout(() => {
            console.log('当前秒数='+new Date().getSeconds())
        }, 3000);
        console.log('此延时定时器id='+timer)
    }
    document.querySelector('#over').onclick = function(){
        //利用之前保存的timer清除延时定时器
        clearTimeout(timer)
        console.log('清除此延时定时器')
    }
</script>

可以看到,第一次点击触发定延时定时器之后,3秒后输出了当前的秒数。第二次点击触发定延时定时器之后,在3秒内清除了此定时器,导致后面不再输出,说明此定时器已被清除

另外,即使定时器被清除,再创建新的定时器时,不会再返回之前的id值,返回的id值会依次累加

3.定时器的一些问题

  • 定时器依附于浏览器运行,如果浏览器没有后台运行的权限,会导致定时器中断执行。在苹果手机中如果用户切换到其他app甚至其他标签,此时定时器就会中断
<script>
    var time = 60
    setInterval(()=>{
        time--
        document.querySelector('#msg').innerHTML = time
    },1000)
</script>

这是pc上chrome浏览器的运行结果,切换到其他标签也不影响此页面的定时器运行(切换出去时是59秒,几秒后切换回来是53秒)

苹果手机上不好截图,我试了59秒时候切换到其他标签,等20秒再切换回来,发现还是58/57的样子,说明浏览器没有后台权限的情况下,定时器会被中断,但是切换回来后依然可以正常执行下去。只是切换浏览器标签就这样,切换到其他app就更不用说了。当前安卓机另说,主要还是后台运行的权限问题。

4.Vue组件中的定时器

  • 1.定时器是页面为单位的,即使定时器所在组件被销毁,定时器依旧存在
//Timer组件
<script>
export default {
  data () {
    return {
      msg: ''
    }
  },
  mounted(){
    setInterval(() => {
      console.log('当前秒数='+new Date().getSeconds())
    }, 1000)
  }
}
</script>

  • 2.注意避免定时器被重复创建,例如上段代码每次切换路由时都会运行mounted钩子函数,导致定时器被重复创建,本来是一秒打印一次的,就会变成一秒打印2次甚至3次...解决办法:在钩子函数beforeDestroy中清除定时器
<script>
export default {
  data () {
    return {
      msg: '',
      timer:null //接收定时器id
    }
  },
  mounted(){
    this.timer = setInterval(() => {
      console.log('当前秒数='+new Date().getSeconds())
    }, 1000)
  },
  beforeDestroy(){
    console.log('此组件将被销毁')
    clearInterval(this.timer)
  }
}
</script>

推荐阅读