今天刚好在看setTimeout()的一个案例,在案例的解析中提到了setTimeout()和setInterval()的使用区别,但是比较理论,所以
决定自己也总结一下,写写例子帮助理解一下。
首先是说说这两个方法的具体时如何使用的。
1、setTimeout()方法
这个方法所有浏览器都支持,setTimeout( ) 是属于 window 的 method, 但我们都是略去 window 这顶层物件名称, 这是用来
设定一个时间, 时间到了, 就会执行一个指定的 method。
定义和用法: setTimeout()方法用于在指定的毫秒数后调用函数或计算表达式。
语法: setTimeout(code,millisec)
参数: code (必需):要调用的函数后要执行的 JavaScript 代码串。millisec(必需):在执行代码前需等待的毫秒数。
提示: setTimeout() 只执行 code 一次。如果要多次调用,请使用 setInterval() 或者让 code 自身再次调用 setTimeout()(即利用递归)。
看完了基本的语法,接下来我写一个很简单的例子说明这个的使用方法。
代码如下:
<!DOCTYPE html>
setTimeout()使用
请等待三秒!
setTimeout("alert('终于等到你了!')",3000)
当我们打开网页3秒时,就会弹出一个框。但是,只会弹出一次,因为 setTimeout()不会自动重复执行,是在载入后的延迟指定
时间去执行一次表达式。
当然,我们也可以让setTimeout()执行函数,而且可以重复执行多次(利用递归),而不是一次。
代码如下:
<!DOCTYPE html>
varx =0;
functioncountSecond()
{
x = x+1;
document.haorooms.haoroomsinput.value = x;
setTimeout("countSecond()",1000)
}
countSecond();
实现的方法就是让函数自身反复调用。
2、setInterval()方法
setInterval() 方法可按照指定的周期(以毫秒计)来调用函数或计算表达式。setInterval() 方法会不停地调用函数,直到
clearInterval() 被调用或窗口被关闭。由 setInterval() 返回的 ID 值可用作 clearInterval() 方法的参数。
语法: setInterval(code,millisec[,"lang"])
参数: code 必需。要调用的函数或要执行的代码串。millisec 必须。周期性执行或调用 code 之间的时间间隔,以毫秒计。
返回值: 一个可以传递给 Window.clearInterval() 从而取消对 code 的周期性执行的值。
如果我们想要每隔3秒就弹出一个框要如何实现呢?
代码如下:
<!DOCTYPE html>
Title
functiontest(){
this.name ="setInternal";
this.waitMes =function(){
varthat =this;
setInterval(function(){
alert(that.name);
},3000);
}
}
varte =newtest();
te.waitMes();
setInterval() 从载入后,每隔指定的时间就执行一次表达式。
3、区别
通过上面可以看出,setTimeout和setinterval的最主要区别是:
1)setTimeout只运行一次,也就是说设定的时间到后就触发运行指定代码,运行完后即结束。如果运行的代码中再次运行同样
的setTimeout命令,则可循环运行。(即 要循环运行,需函数自身再次调用 setTimeout());而 setinterval是循环运行的,即每
到设定时间间隔就触发指定代码。这是真正的定时器。
2)setinterval使用简单,而setTimeout则比较灵活,可以随时退出循环,而且可以设置为按不固定的时间间隔来运行,比如第
一次1秒,第二次2秒,第三次3秒。
值得注意的是:
setTimeout(function(){
console.log(1);
});
console.log(0);
这里,实际上,把setTimeout的第二个参数设置为0s,并不是立即执行函数的意思,只是把函数放入异步队列。浏览器先执行完同步队列里的任务,才会去执行异步队列中的任务。
setInterval()原理与setTimeout(),也是讲代码放入异步队列中。但是,setInterval()存在一个问题,
使用setInterval()的问题在于,定时器代码可能在代码再次被添加到队列之前还没有完成执行,结果导致定时器代码连续运行好几次,而之间没有任何停顿。而javascript引擎对这个问题的解决是:当使用setInterval()时,仅当没有该定时器的任何其他代码实例时,才将定时器代码添加到队列中。这确保了定时器代码加入到队列中的最小时间间隔为指定间隔。
但是,这样会导致两个问题:1、某些间隔被跳过;2、多个定时器的代码执行之间的间隔可能比预期的小。
两者的工作原理:大家都知道,JavaScript是单线程执行的,setTimeout和setInterval执行原理其实也很简单。
setTimeout会在调用后的millisec时间间隔后往事件队列里添加回调函数,然后等待执行。
setInterval会按照第二个参数的周期时间周期性的往事件队列添加回调函数,然后等待执行,这里的一个注意点是如果事件队列里的回调函数还没有执行,不会重复添加。
注:html5规定setTimeout和setInterval的延迟时间最少为4ms. 所以setTimeout(function(){},0)其实是setTimeout(function(){}, 4)。
如果上面代码中的onclick事件处理程序执行了300ms,那么定时器的代码至少要在定时器设置之后的300ms后才会被执行。队列中所有的代码都要等到javascript进程空闲之后才能执行,而不管它们是如何添加到队列中的。如下图:
如图所示,尽管在255ms处添加了定时器代码,但这时候还不能执行,因为onclick事件处理程序仍在运行。定时器代码最早能执行的时机是在300ms处,即onclick事件处理程序结束之后。
实际上,把setTimeout的第二个参数设置为0s,并不是立即执行函数的意思,只是把函数放入异步队列。浏览器先执行完同步队列里的任务,才会去执行异步队列中的任务。
验证例子:
例一:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>菜鸟教程(runoob.com)</title>
<script>
(function(){
var i=0;
setTimeout(function(){
document.getElementById("demo").innerHTML=1233131123;
},2500)
setInterval(function(){
i++;
document.getElementById("demo").innerHTML=i;
},1000)
})()
</script>
</head>
<body>
<h1>我的第一个 JavaScript 程序</h1>
<p id="demo">这是一个段落</p>
<button type="button" onclick="displayDate()">显示日期</button>
</body>
</html>
此代码结果显示先后顺序:
1(1s)、2(2s)、1233131123(2.5s)、3(3s)、4(4s)........
原理分析:
例二:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>菜鸟教程(runoob.com)</title>
<script>
(function(){
var i=0;
setInterval(function(){
i++;
document.getElementById("demo").innerHTML=i;
setTimeout(function(){
document.getElementById("demo").innerHTML=1233131123;
},2500)
},1000)
})()
</script>
</head>
<body>
<h1>我的第一个 JavaScript 程序</h1>
<p id="demo">这是一个段落</p>
<button type="button" onclick="displayDate()">显示日期</button>
</body>
</html>
效果及分析: