JavaScript 定时器
setInterval();
setTimeout();
clearInterval();
clearTimeout();
全局对象window上的方法,内部函数this指向window
注意 :setInterval(“func()”,1000);
定时器分两种
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() 执行变量 i 加加
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 才对,程序有时候准有时候不准

程序执行所损耗的毫秒几乎可以不记,程序是以微秒的速度来执行的,首先一定要记住一个结论:setIntervals 是非常不准
然后简单的解释一下,
js 引擎后面有一个执行队列,它会把任务按照时间片段去分解,把很多任务的片段排列好,然后往队列里面放,队列依次往执行马达里面去输送,然后马达引擎是单线程同一时间只能执行一个片段,这样依次往里送它才能执行任务。
setInterval 每隔 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 清除定时器的方法

当然了,不接收返回值也知道返回值是数字 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 秒停掉这个电影把权限关掉。
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毫秒执行一下字符串里面的代码这是一种特殊的形式,正常情况下不会写种情况,但这种情况确实存在

练习题,
写一个计时器,到三分钟停止
<!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>