今天剛好在看setTimeout()的一個案例,在案例的解析中提到了setTimeout()和setInterval()的使用區(qū)別欲低,但是比較理論谴麦,所以
決定自己也總結一下,寫寫例子幫助理解一下伸头。
? ? ? ?首先是說說這兩個方法的具體時如何使用的。
1舷蟀、setTimeout()方法
? ? ? 這個方法所有瀏覽器都支持恤磷,setTimeout( ) 是屬于 window 的 method, 但我們都是略去 window 這頂層物件名稱, 這是用來
設定一個時間, 時間到了, 就會執(zhí)行一個指定的 method。
? ? ? 定義和用法: setTimeout()方法用于在指定的毫秒數(shù)后調(diào)用函數(shù)或計算表達式野宜。
? ? ? 語法: setTimeout(code,millisec)
? ? ? 參數(shù): code (必需):要調(diào)用的函數(shù)后要執(zhí)行的 JavaScript 代碼串扫步。millisec(必需):在執(zhí)行代碼前需等待的毫秒數(shù)。 ?
?提示: setTimeout() 只執(zhí)行 code 一次匈子。如果要多次調(diào)用河胎,請使用 setInterval() 或者讓 code 自身再次調(diào)用 setTimeout()(即利用遞歸)。
? ? ? 看完了基本的語法虎敦,接下來我寫一個很簡單的例子說明這個的使用方法游岳。
代碼如下:
<!DOCTYPE html>
setTimeout()使用
請等待三秒!
setTimeout("alert('終于等到你了!')",3000)
? ? ? 當我們打開網(wǎng)頁3秒時其徙,就會彈出一個框胚迫。但是,只會彈出一次唾那,因為?setTimeout()不會自動重復執(zhí)行访锻,是在載入后的延遲指定
時間去執(zhí)行一次表達式。
當然,我們也可以讓setTimeout()執(zhí)行函數(shù)期犬,而且可以重復執(zhí)行多次(利用遞歸)河哑,而不是一次。
代碼如下:
<!DOCTYPE html>
varx =0;
functioncountSecond()
? ? ? ? {
x = x+1;
document.haorooms.haoroomsinput.value = x;
setTimeout("countSecond()",1000)
? ? ? ? }
? ? countSecond();
? ? ? ?實現(xiàn)的方法就是讓函數(shù)自身反復調(diào)用龟虎。
2璃谨、setInterval()方法
setInterval() 方法可按照指定的周期(以毫秒計)來調(diào)用函數(shù)或計算表達式。setInterval() 方法會不停地調(diào)用函數(shù)遣总,直到?
clearInterval() 被調(diào)用或窗口被關閉睬罗。由 setInterval() 返回的 ID 值可用作 clearInterval() 方法的參數(shù)。
語法: setInterval(code,millisec[,"lang"])
? ? ?參數(shù): code 必需旭斥。要調(diào)用的函數(shù)或要執(zhí)行的代碼串容达。millisec 必須。周期性執(zhí)行或調(diào)用 code 之間的時間間隔垂券,以毫秒計花盐。
返回值: 一個可以傳遞給 Window.clearInterval() 從而取消對 code 的周期性執(zhí)行的值。
? ? ?如果我們想要每隔3秒就彈出一個框要如何實現(xiàn)呢菇爪?
代碼如下:
<!DOCTYPE html>
Title
functiontest(){
this.name ="setInternal";
this.waitMes =function(){
varthat =this;
setInterval(function(){
? ? ? ? ? ? ? ? alert(that.name);
},3000);
? ? ? ? }
? ? }
varte =newtest();
? ? te.waitMes();
? ? ? ?setInterval() 從載入后算芯,每隔指定的時間就執(zhí)行一次表達式。
3凳宙、區(qū)別
? ? ?通過上面可以看出熙揍,setTimeout和setinterval的最主要區(qū)別是:
? ? 1)setTimeout只運行一次,也就是說設定的時間到后就觸發(fā)運行指定代碼氏涩,運行完后即結束届囚。如果運行的代碼中再次運行同樣
的setTimeout命令,則可循環(huán)運行是尖。(即 要循環(huán)運行意系,需函數(shù)自身再次調(diào)用 setTimeout());而 setinterval是循環(huán)運行的饺汹,即每
到設定時間間隔就觸發(fā)指定代碼蛔添。這是真正的定時器。
? ? 2)setinterval使用簡單兜辞,而setTimeout則比較靈活迎瞧,可以隨時退出循環(huán),而且可以設置為按不固定的時間間隔來運行逸吵,比如第
一次1秒夹攒,第二次2秒,第三次3秒胁塞。
值得注意的是:
setTimeout(function(){
? ? console.log(1);
});
console.log(0);
這里咏尝,實際上压语,把setTimeout的第二個參數(shù)設置為0s,并不是立即執(zhí)行函數(shù)的意思编检,只是把函數(shù)放入異步隊列胎食。瀏覽器先執(zhí)行完同步隊列里的任務,才會去執(zhí)行異步隊列中的任務允懂。
setInterval()原理與setTimeout(),也是講代碼放入異步隊列中厕怜。但是,setInterval()存在一個問題蕾总,
使用setInterval()的問題在于粥航,定時器代碼可能在代碼再次被添加到隊列之前還沒有完成執(zhí)行,結果導致定時器代碼連續(xù)運行好幾次生百,而之間沒有任何停頓递雀。而javascript引擎對這個問題的解決是:當使用setInterval()時,僅當沒有該定時器的任何其他代碼實例時蚀浆,才將定時器代碼添加到隊列中缀程。這確保了定時器代碼加入到隊列中的最小時間間隔為指定間隔。
但是市俊,這樣會導致兩個問題:1杨凑、某些間隔被跳過;2摆昧、多個定時器的代碼執(zhí)行之間的間隔可能比預期的小撩满。
兩者的工作原理:大家都知道,JavaScript是單線程執(zhí)行的绅你,setTimeout和setInterval執(zhí)行原理其實也很簡單鹦牛。
setTimeout會在調(diào)用后的millisec時間間隔后往事件隊列里添加回調(diào)函數(shù),然后等待執(zhí)行勇吊。?
setInterval會按照第二個參數(shù)的周期時間周期性的往事件隊列添加回調(diào)函數(shù),然后等待執(zhí)行窍仰,這里的一個注意點是如果事件隊列里的回調(diào)函數(shù)還沒有執(zhí)行汉规,不會重復添加。
注:html5規(guī)定setTimeout和setInterval的延遲時間最少為4ms. 所以setTimeout(function(){},0)其實是setTimeout(function(){}, 4)驹吮。
如果上面代碼中的onclick事件處理程序執(zhí)行了300ms针史,那么定時器的代碼至少要在定時器設置之后的300ms后才會被執(zhí)行。隊列中所有的代碼都要等到javascript進程空閑之后才能執(zhí)行碟狞,而不管它們是如何添加到隊列中的啄枕。如下圖:
如圖所示,盡管在255ms處添加了定時器代碼族沃,但這時候還不能執(zhí)行频祝,因為onclick事件處理程序仍在運行泌参。定時器代碼最早能執(zhí)行的時機是在300ms處,即onclick事件處理程序結束之后常空。
實際上沽一,把setTimeout的第二個參數(shù)設置為0s,并不是立即執(zhí)行函數(shù)的意思漓糙,只是把函數(shù)放入異步隊列铣缠。瀏覽器先執(zhí)行完同步隊列里的任務,才會去執(zhí)行異步隊列中的任務昆禽。
驗證例子:
例一:
<!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>
效果及分析: