前言
在开发过程中,我们总会遇到一些功能需要使用定时器来实现,我们常用的有:setInterval();setTimeout();clearInterval();clearTimeout()。今天让我们来仔细的研究一下吧~
1. setInterval()
setInterval()方法重复调用一个函数或执行一个代码段,在每次调用之间具有固定的时间延迟。通俗来讲即setInterval()方法内的函数片段会一直在固定的时间延迟后重复执行,直到清除本次重复操作的唯一辨识符intervalID。
语法
let intervalID = window.setInterval(func, delay[, param1, param2, ...]);
参数:
- intervalID 是此重复操作的唯一辨识符,可以作为参数传给clearInterval()。
- func 是你想要重复调用的函数。
- delay 是每次延迟的毫秒数 (一秒等于1000毫秒),函数的每次调用会在该延迟之后发生。和setTimeout一样,实际的延迟时间可能会稍长一点。
常见应用:打字机效果, 计时器
一个小demo:
// 自动结束的计时器
var timesRun = 0;
var interval = setInterval(function(){
timesRun += 1;
if(timesRun === 60){
clearInterval(interval);
}
}, 1000);
2. setTimeout()
setTimeout()方法设置一个定时器,该定时器在定时器到期后执行一个函数或指定的一段代码。通俗来讲即setTimeout()在指定的毫秒数后调用函数或计算表达式。只执行一次,执行完毕后定时器就停止(定时器还在,但不再调用)。
语法
var timeoutID=scope. setTimeout(function, delay, paraml, param2,..]);
var timeoutID=scope. setTimeout(function[, delay]);
参数:
- function 是你想要在到期时间(delay毫秒)之后执行的函数。
- delay(可选) 延迟的毫秒数 (一秒等于1000毫秒),函数的调用会在该延迟之后发生。如果省略该参数,delay取默认值0,意味着“马上”执行,或者尽快执行。不管是哪种情况,实际的延迟时间可能会比期待的(delay毫秒数) 值长,主要是因为(1)setTimeout在浏览器中有一个最小约定值(4ms-10ms);(2)浏览器在执行过程中会先执行主线程代码,待主线程代码运行完毕后才会再执行setTimeout()
- param1, ..., paramN(可选) 附加参数,一旦定时器到期,它们会作为参数传递给function
返回值
返回值timeoutID是一个正整数,表示定时器的编号。这个值可以传递给clearTimeout()来取消该定时器。
常见应用:
- 在vue中想要页面加载后获取ref元素时,可以将要获取的元素代码写入setTimeout(() => {}, 0),或者使用vue官方给出的
this.$nextTick(() => {
this.msg2 = this.$refs.msgDiv.innerHTML
})
- 等待几秒后执行的操作
- 倒计时(demo如下)
<html>
<head>
<script>
x = 60
function countSecond(){
x --
document.fm.displayBox.value=x
setTimeout("countSecond()", 1000)
}
</script>
</head>
<body bgcolor=lightcyan text=red><p></br>
<form name=fm>
<input type="text" name="displayBox"value="0" size=4 >
</form>
<script>
countSecond()
</script>
</body>
</html>
3. clearInterval() 和 clearTimeout()
取消setInterval或setTimeout设置的重复定时任务。setTimeout()和setInterval()共用一个编号池,技术上,clearTimeout()和 clearInterval() 可以互换。但是,为了避免混淆,不要混用取消定时函数。
语法
window.clearInterval(intervalID)
window.clearTimeout(timeoutID)
demo:在一个网页中运行如下脚本,并且点击一次页面。一秒钟后你会看见弹出一条信息。如果你在一秒内不停点击页面,弹出框将不再出现。
var alarm = {
remind: function(aMessage) {
alert(aMessage);
delete this.timeoutID;
},
setup: function() {
this.cancel();
var self = this;
this.timeoutID = window.setTimeout(function(msg) {self.remind(msg);}, 1000, "Wake up!");
},
cancel: function() {
if(typeof this.timeoutID == "number") {
window.clearTimeout(this.timeoutID);
delete this.timeoutID;
}
}
};
window.onclick = function() { alarm.setup() };
注意: 传入一个错误的 ID 给 clearTimeout()或clearInterval()不会有任何影响;也不会抛出异常
setInterval() 和 setTimeout()的区别
setTimeout():只执行一次; setInterval():重复执行直到手动暂停或窗关闭。
setInterval的弊端和解决方案
弊端
- setInterval对自己调用的代码是否报错漠不关心。即使调用的代码报错了,它依然会持续的调用下去
- setInterval无视网络延迟。在使用ajax轮询服务器是否有新数据时,必定会有一些人会使用setInterval,然而无论网络状况如何,它都会去一遍又一遍的发送请求,如果网络状况不良,一个请求发出,还没有返回结果,它会坚持不懈的继续发送请求,最后导致的结果就是请求堆积。
- setInterval并不定时。如果它调用的代码执行的时间小于定时的时间,它会跳过调用,这就导致无法按照你需要的执行次数或无法得到你想要的结果。
解决方法
使用setTimeout代替setInterval。可以给setTimeout设置时间后,在最后调用自身。如果希望“匀速”触发。可以计算代码执行时间,用希望的延迟减去上次执行的时间。