Go to comments

JavaScript 定时器


定时器分两种,

setInterval()     从名字上叫定时器不太严谨,应该叫定时循环器

setTemeout()   才是真正的定时器,隔了一段时间之后,再执行一个事。换句话说它启的是一个推迟的作用而不是循环执行


一、定时循环器

setInterval() 每隔1000毫秒就执行一次函数,永远没有休止,我们管它叫"定时器"每隔多次多长时间执行一次

setInterval(function(){  // 这个function不用写名字

    console.log('a');

},1000); // 1000毫秒的意思


可以把时间调小,调成10速度就非常快,也可以调大2000毫秒,两秒执行一次

setInterval(function(){

    console.log('a');

},10);


间隔时间设置到变量time上

var time = 1000; // 间隔时间time

setInterval(function(){

    console.log('a');

},time); // time这里就是1000

time = 2000; // time在这改成2000,定时器里能变成2000吗?

不可能变,定时器里time会取一次值,每隔time时间执行函数会多次执行函数,但是识别time只识别一次,当初写多少就是多少,不要试图通过改变time来影响setInterval()执行的快慢,当初写1000就是1000后面改不了


可以用setInterval()执行变量加加

var i = 0;

setInterval(function(){
    
    i ++;
    console.log(i);

},1000);


可以利用setInterval()做很多东西,

定时间每隔一段时间执行一次函数,这个函数里面的变量就可以变,

通过变化再通过重复执行可以出现很多东西,然后通过这种反复的执行有时间隔的去执行,我们还是可以实现很多状态的连续改变。


测试一下,"定时器"到底准不准?

var firstTime = new Date().getTime();

setInterval(function(){

    var lastTime = new Date().getTime();

    console.log(lastTime - firstTime);
    
    firstTime = lastTime; // 每次都是新生的时刻,减去上一时刻

}, 1000);

应该都是1000才对,程序有时候准有时候不准

图片.png


程序执行所损耗的毫秒几乎可以不记,程序是以微秒的速度来执行的,首先一定要记住一个结论:setIntervals是非常不准。


然后简单的解释一下,

js引擎后面有一个执行队列,它会把任务按照时间片段去分解,把很多任务的片段排列好,然后往队列里面放,队列依次往执行马达里面去输送,然后马达引擎是单线程同一时间只能执行一个片段,这样依次往里送它才能执行任务。


setIntervals每隔1000毫秒放到队列后面,具体什么时候执行没法保证。当然也不只是这个方面,如果只是这个方面不准永远是慢,为什么还有快的情况!

简单透露一下setInterval的排列机制是基于红黑数的。


PS: 

原来业内标志js最底层的书叫《高性能javascript》,现在有一本书刷新记录叫《你不知道的javascript》是最冷门的一些知识,看完后js知识就透了。


clearInterval() 关闭定时器


在clearInterval之前先说一下,

setInterval是window上的方法,由于是window上的方法,我们在全局上不这么写"indow.setInterval也会上GO里面去找,所以不写window也没问题,这是window的一个特点。


setInterval每一个都会返回一个"数字"值,作为它的唯一标识

var timer = setInterval(function(){},1000)
console.log(timer);  // 1


var timer2 = setInterval(function(){},1000)
console.log(timer2); // 2


var timer3 = setInterval(function(){},1000)
console.log(timer3); // 3


按照这个唯一标识,可以把定时器清除掉

var i = 0;

var timer = setInterval(function(){

    console.log(i++);
    
    if(i > 10){
        clearInterval(timer); // 清除定时器
    }

}, 10);

数到10定时器就清除了,这是clearInterval清除定时器的方法

图片.png


当然了,不接收返回值也知道返回值是数字1,直接在clearInterval(1)也行。但这样写不科学,别人不知道为什么写这个1

var i = 0;

setInterval(function(){
    
    console.log(i++);
    if(i > 10){
        clearInterval(1);
    }

},1000);


二、定时器

setTemeout() 1000毫秒之后在执行,并且执行一次

setTimeout(function(){

    console.log('啦啦');

}, 1000);


setTimeout有什么真实的应用呢?

比如一段电影有一个30秒的试看时间,到30秒之后就看不了,会延迟30秒停掉这个电影把权限关掉。


clearTimeout()


setTimeout它用不用取消?

一部电影同样给五分钟的免费观影时间,五分钟之后就要交钱观看,在这五分钟以内你登录会员了,那五分钟之后就不用停了,那提前预设的任务就应该被取消。


现实在公司里开发的时候,一个移动端的页面从刚开始运行,到整个页面展示结束需要加载3秒左右,最开始设计在三秒钟内不展示广告,在第五秒时才展示广告,所以在第五秒的时候setTimeout把广告展示出来。

但是有一个情况,有两个广告一个弹屏的广告、一个固定位置的广告,五秒钟之内如果点击了固定位置的广告,弹屏的广告就不在展现了,因为两个广告是一回事。


clearTimeout()清除也需要返回值

var timer = setTimeout(function(){

    console.log('A');

}, 1000);

clearTimeout(timer);

"A"永远出不来了,还没执行就clearTimeout()清除了


setTimeout返回的唯一标识和setInterval返回的唯一标识,不会重叠的返回的是依次的

var timer1 = setInterval(function(){}, 1000);
var timer2 = setTimeout(function(){}, 1000);

console.log(timer1); // 返回 1
console.log(timer2); // 返回 2


三、全局对象window上的方法,内部函数this指向window

setTimeout和setInterval全是window上的方法,所以内部函数里的this指向的是window

setInterval(function(){

    console.log(this); // Window {parent: Window, opener: null, top: Window, length: 0, frames: Window, …}
}
, 1000);


注意setInterval(“func()”,1000);

最后一个注意点,无论是setInterval()还是setTimeout()它们都可以以另一种形式来展现,


第一种形式里面写的是function

setInterval(function () {}, 1000);


另一种形式展现是这样,里面可以写一些字符串,这个字符就会当做js代码来执行

setInterval("console.log('巴拉巴拉')", 1000); // 每个1000毫秒执行一下字符串里面的代码

这是一种特殊的形式,正常情况下不会写种情况,但这种情况确实存在

图片.png


练习题,

写一个计时器,到三分钟停止

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>练习题 - 计时器</title>
<style>
input{
    border:1px solid rgba(0,0,0,0.2);
    text-align: right;
}
</style>
</head>
<body>

minutes:<input type="text" value="0">
seconds:<input type="text" value="0">

<script>

var minutesNode = document.getElementsByTagName('input')[0];
var secondsNode = document.getElementsByTagName('input')[1];

var minutes = 0,
    seconds = 0;

var timer = setInterval(function(){

    seconds ++;
    if(seconds == 60){
        seconds = 0;
        minutes ++;
    }

    secondsNode.value = seconds;
    minutesNode.value = minutes;

    if(minutes == 3){
        clearInterval(timer);
    }


}, 100);

</script>
</body>
</html>



Leave a comment 0 Comments.

Leave a Reply

换一张