JS中两种定时器及其清除

JS的两种定时器

window.setTimeout([function],[interval])

设置一个定时器,并且设定了一个等待的时间,当到达时间后,执行对应的方法,当方法执行完成定时器停止。

window.setInterval([function],[interval])

设置一个定时器,并且设定了一个等待的时间,当到达时间后,执行对应的方法。

当方法执行完成,定时器并没有停止,以后每隔这么长的时间都会重新的执行对应的方法,直到我们手动清除定时器为止。

注意:setTimeout() 只执行 code 一次。如果要多次调用,请使用 setInterval() 或者让 code 自身再次调用 setTimeout()。

定时器返回值

JS中的定时器是有返回值的,返回值是一个数字,代表当前是第几个定时器。

1

2

3

var timer1=window.setTimeout(function(){},1000);  //timer1->1 当前是第一个定时器

var timer2=window.setTimeout(function(){},1000);  //timer2->2` 当前是第二个定时器

var timer3=window.setTimeout(function(){},1000);   //timer3->3 当前是第三个定时器

需要注意的是,定时器即使清除了,其返回值也不会清除,之后设置的定时器的返回值也会在其返回值的基础上继续向后排。

怎么清除定时器

若不及时清理定时器,可能会导致内存溢出的风险。所以当我们在使用定时器的时候,就需要考虑在合适的时间清除。

清除定时器有两个函数:

  • setTimeout的销毁函数为clearTimeout

  • setInterval的销毁函数为clearInterval

setInterval对象或setTimeout对象,这两种定时器对象只会随着窗口对象的销毁才从栈空间回收。无法通过更改变量的指针指向null的方式通知垃圾回收机自动回收。如果打算在窗口对象关闭之前销毁窗口对象的栈内存中的setInterval对象只能通过clearInterval销毁它

clearTimeout(id_of_settimeout)

定义:阻止/取消 setTimeout() 方法设置的定时执行函数。

参数:id_of_settimeout是调用 setTimeout() 函数时所返回的ID值,使用该返回标识符作为参数,可以取消该 setTimeout() 所设定的定时执行操作。

注意: 要使用 clearTimeout(id_of_setinterval) 方法, 在创建执行定时操作时要使用全局变量:

1

2

var myVar = setTimeout(function(){ alert("Hello"); }, 3000);

clearTimeout(myVar);

  • 是否需要及时清理setTimeOut

1

2

3

4

function testTimeout () {

    console.log('1111')

    console.log(setTimeout(testTimeout, 3000));

}

上面代码在递归调用testTimeout,然而setTimeout会一直生成setTimeout对象;虽然会被GC回收但时间不确定,这样做比较危险,可能会导致内存溢出。

所以我们应该在每次 setTimeout 之前调用 clearTimeout,防止不断创建setTimeout对象而未被GC回收。

1

2

3

4

5

6

7

8

9

10

11

var timeHandle = null;

function testTimeout () {

    if (timeHandle) {

        // 调用之前,先清理,防止一直生成对象

        // ps. setInterval 定时器也应该按这种模式处理

        clearTimeout(timeHandle);

        timeHandle = null;

    }

    console.log('1111');

    console.log(timeHandle = setTimeout(testTimeout, 3000));

}

clearInterval(id_of_setinterval)

定义: 可取消/停止由 setInterval() 函数设定的定时执行操作。

参数:id_of_setinterval是调用 setInterval() 函数时所返回的 ID 值,只有使用该返回标识符作为参数,才可以取消该 setInterval() 所设定的定时执行操作。

注意: 要使用 clearInterval() 方法, 在创建执行定时操作时要使用全局变量:

1

2

var myVar = setInterval(function(){ myTimer() }, 1000);

clearInterval(myVar);

  • 是否需要及时清理setInterval

1

2

3

4

function testInterval () {

    console.log('1111')

    console.log(setInterval(testInterval, 3000));

}

上面代码在递归调用testInterval,然而setInterval会一直生成setInterval对象;虽然会被GC回收但时间不确定,这样做比较危险,可能会导致内存溢出。

所以我们应该在每次 setInterval 之前调用 clearInterval,防止不断创建setInterval对象而未被GC回收。

1

2

3

4

5

6

7

8

9

10

var timeHandle = null;

function testInterval () {

    if (timeHandle) {

        // 调用之前,先清理,防止一直生成对象

        clearInterval(timeHandle);

        timeHandle = null;

    }

    console.log('1111');

    console.log(timeHandle = setInterval(testInterval, 3000));

}

扩展知识:使用setTimeout模拟setInterval行为

通常情况下:递归的方式使用setTimeOut(),效果相当于使用setInterval()

好处:

  • 简化代码

  • 保证异步队列的函数调用顺序的精准度,setInterval的缺陷会导致数据量大的时候,异步队列的函数调用出现执行顺序的错乱。比如这个函数还没执行完又开始执行下一个,递归则不会,递归是当前函数执行完才在栈空间递归创建函数的下一个实体并调用。

1

2

3

4

5

6

7

8

9

10

11

12

//实现的方法挺简单的 ,如下代码

//参数: 毫秒  需要执行的方法

function console1() {

    console.log(111);

    if(timer){

        clearTimeout(timer);

    }

    timer = setTimeout(function(){

        console1();

    }, 3000);

}

console1()

posted @ 2022-05-29 00:15  RHCHIK  阅读(7327)  评论(0编辑  收藏  举报