javascript定时器(setTimeout和setInterval)的使用详解

  最近在做项目中遇到了一个关于setInterval的问题。需求是能通过改变setInterval中的间隔时间,实现快进2倍、快进4倍 的功能,当快进速度超过4倍时,播放速度恢复到正常速度。可是但我点击三次过后,发现速度并没有恢复到正常速度,速度反而是更快了。一开始没多想,就在每次点击之后调用clearInterval(timer)方法,发现问题解决了,但是我并不知道为什么这样做能够解决这个问题。后来通过查阅关于setTimeout和setInterval的相关资料,写出了这篇文章,来跟大家一起探讨一下。

1、setTimeout(code,millisec)

参数描述
code要执行的代码
millisec表示需要等待的时间,表示在millisec毫秒后将code加入到当前执行线程中

  setTimeOut中的第一个参数(code)可以是字符串也可以是函数,但是字符串可能导致性能损失,所以最好是使用函数。且code只会被执行一次。调用cleartimeout()可以终止setTimeOut方法的执行。下面来看几个例子

document.getElementById("btn").onclick = function() {
	var start = new Date().getTime();
	setTimeout(function() {
		console.log((new Date().getTime() - start) + "毫秒后开始执行setTimeout中的代码");
	}, 1000);
	test();
}
function test() {
	var stime = new Date().getTime();
	var content = ""
	for(var i = 0; i < 5000000; i++) {
		content = content + "34636";
	}
	var etime = new Date().getTime()
	console.log("循环执行了" + (etime - stime) + "毫秒");
}   
复制代码

输出结果为:

document.getElementById("btn").onclick = function() {
	var start = new Date().getTime();
	setTimeout(function() {
		console.log((new Date().getTime() - start) + "毫秒后开始执行setTimeout中的代码");
	}, 500);
	test();
}
function test() {
	var stime = new Date().getTime();
	var content = ""
	for(var i = 0; i < 5000000; i++) {
		content = content + "34636";
	}
	var etime = new Date().getTime()
	console.log("循环执行了" + (etime - stime) + "毫秒");
}   
复制代码

输出结果为:

document.getElementById("btn").onclick = function() {
	var start = new Date().getTime();
	setTimeout(function() {
		console.log((new Date().getTime() - start) + "毫秒后开始执行setTimeout中的代码");
	}, 0);
	test();
	console.log("函数执行完毕")
}
function test() {
	var stime = new Date().getTime();
	var content = ""
	for(var i = 0; i < 5000000; i++) {
		content = content + "34636";
	}
	var etime = new Date().getTime()
	console.log("循环执行了" + (etime - stime) + "毫秒");
}   
复制代码

输出结果为:

  上面的代码表示:当javscript代码运行到setTimeout时,500/1000/0毫秒后将setTimeout里面的函数加入到javascript执行队列中。如果队列为空的话,500/1000/0毫秒后将执行setTimeout的函数,如果此时队列不是空的,那么就要等前面的代码执行完了才运行setTimeout中的函数。

  总结:从第三段代码,setTimeout中的第二个参数为0可以看出setTimeout总是在创建它的函数体运行完毕之后,才会去执行。

  如果需要取消超时调用的话,需要将setTimeout()赋值给某个变量,然后调用clearTimeout()方法,代码如下:

var timer = setTimeout(function() {
	console.log("我是测试数据");
}, 0);
clearTimeout(timer);
复制代码

2、setInterval(code,millisec)

参数描述
code要执行的代码
millisec表示需要等待的时间,表示在millisec毫秒后将code加入到当前执行线程中

  setInterval和setTimeOut的参数意义是一样的。只不过setTimeout中的code只会被执行一次,而setTimeout中的code会不断的被执行。调用clearInterval()可以终止setInterval方法的执行。这种重复定时器有两个问题:

  • 某些间隔会被跳过;
  • 多个定时器的代码执行之间的间隔可能比预期的要小。

3、serInterVal的原理分析

下面来看一个serInterVal的例子
<button id="btn1">开始</button>
<script type="text/javascript">    
window.onload=function(){
	var i=1;
	document.getElementById("btn").onclick=function(){
		console.log("第"+(i++)+"此点击")
		setInterval(function(){
			console.log(new Date().getSeconds())
		},1000)
	}
}
</script>
复制代码

输出结果如下:

  结果分析:当我点击第一次时,setInterval中的函数体每1秒运行一次,当我点击第二次时,setInterval中的函数体每1/2秒运行一次,当我点击第三次时,setInterval中的函数体每1/3秒运行一次,当我点击第三次时,setInterval中的函数体每1/4秒运行一次。出现这样的原因是因为点击4次就调用了4次serInterval方法,相当于调用了4个定时器。用如下的图来进行分析能很好地解释为什么会出现上面情况的原因了。

  结果分析:如上图所示,在0-1s内点击2次,在1-2s内点击第3次,在2-3内点击第4次,那么在第2秒内会调用两次setInterval中的函数体。在第3秒内会调用3次函数体,第4秒内会调用第4次函数体。

下面是验证过程: 代码如下:

<button id="btn1">开始</button>
<button id="btn2">结束</button>
<script type="text/javascript">   
window.onload = function() {
	var i = 1;
	document.getElementById("btn1").onclick = function() {
		console.log("第" + (i++) + "此点击")
		var timer = setInterval(function() {
			console.log(new Date().getSeconds())			
		}, 1000);
		document.getElementById("btn2").onclick = function() {
			console.log("点击结束按钮");
			clearInterval(timer);
		}
	};
}
</script>
复制代码

运行结果如下:

  如上图所示,点击3次按钮后,每1秒内调用3次setInterval中的函数,但点击结束按钮后,每1秒内还运行2次setInterval中的函数。运行结果证明我上面的分析是对的。 为了解决上面点击开始按钮多次会调用多个setInterval的情况,我总结了下面这个方法供大家参考。代码如下所示:

<button id="btn1">开始</button>
<button id="btn2">结束</button>
<script type="text/javascript">   
window.onload = function() {
	var i = 1;
	var timer=null;
	document.getElementById("btn1").onclick = function() {
		if(timer){
			clearInterval(timer);
		}
		console.log("第" + (i++) + "此点击");
		timer = setInterval(function() {
			console.log(new Date().getSeconds())						
		}, 1000);	
	};
	document.getElementById("btn2").onclick = function() {
		console.log("点击结束按钮");
		clearInterval(timer);
	}				
}
</script>
复制代码

先点击2次开始按钮,然后再点击结束按钮,操作输出结果如下:

  总结:调用setInterval方法时,要先调用clearInterval方法清除setInterval运行后返回的timer。调用setTimeout方法也一样,要先调用cleartimeout方法清除setTimeout运行后返回的timer。
  点击快进按钮是播放速度快进2倍和快进4倍也就是把时间间隔设置成原来的1/2和1/4即可,但同时要调用clearInterval方法清除setInterval运行后返回的timer,这样才能达到预期的效果。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值