定時(shí)器主要由setTimeout()和setInterval()這兩個(gè)函數(shù)完成座咆。
1.setTimeout()函數(shù)用來(lái)指定某個(gè)函數(shù)或某段代碼,在多少毫秒之后執(zhí)行。它返回一個(gè)整數(shù)蛔翅,表示定時(shí)器的編號(hào)瓶殃,以后可以用來(lái)取消這個(gè)定時(shí)器充包。
syntax:
<pre>
var timerId=setTimeout(func|code,delay)
</pre>
示例:
<pre>
function showTime(){
console.log(1);
}
setTimeout(showTime(),1000);//輸出結(jié)果為1
</pre>
注意:為了便于JavaScript引擎優(yōu)化代碼,setTimeout方法一般總是采用函數(shù)名的形式遥椿。
2.setInterval()
setInterval()函數(shù)的用法與setTimeout完全一致基矮,區(qū)別僅僅在于setInterval指定某個(gè)任務(wù)每隔一段時(shí)間就執(zhí)行一次,也就是無(wú)限次的定時(shí)執(zhí)行冠场。
示例:
<pre>
var timer=setInterval(function(){
console.log(2);
},1000);
</pre>
setInterval指定的是“開始執(zhí)行”之間的間隔家浇,并不考慮每次任務(wù)執(zhí)行本身消耗所消耗的時(shí)間。因此實(shí)際上碴裙,兩次執(zhí)行之間的間隔會(huì)小于指定的時(shí)間钢悲。比如,setInterval指定每100ms執(zhí)行一次舔株,每執(zhí)行需要5ms,那么第一次執(zhí)行結(jié)束后95毫秒莺琳,第二次執(zhí)行就會(huì)開始。如果某次執(zhí)行耗時(shí)特別長(zhǎng)载慈,比如需要105毫秒惭等,那么它結(jié)束后,下一次執(zhí)行就會(huì)立即開始办铡。
為確保兩次執(zhí)行之間有固定的時(shí)間間隔辞做,可以不用setInterval,而是每次執(zhí)行結(jié)束之后寡具,使用setTimeout指定下一次執(zhí)行的具體時(shí)間凭豪。
示例:
<pre>
var i=1;
var timer=setTimeout(function(){
alert(i++);
timer=setTimeout(arguments.callee,2000);
},2000);
</pre>
setTimeout和setInterval的運(yùn)行機(jī)制是,將指定的代碼移出本次執(zhí)行晒杈,等到下一輪Event Loop時(shí)嫂伞,再檢查是否到了指定時(shí)間。如果到了拯钻,就執(zhí)行對(duì)應(yīng)的代碼帖努;如果不到,就等到了再下一輪Event Loop時(shí)重新判斷粪般。這意味著拼余,setTimeout指定的代碼,必須等到本次執(zhí)行的所有代碼都執(zhí)行完亩歹,才會(huì)執(zhí)行匙监。
每一輪EventLoop時(shí)凡橱,都會(huì)將“任務(wù)隊(duì)列”中需要執(zhí)行的任務(wù),一次執(zhí)行完亭姥。setTimeout和setInterval都是把任務(wù)添加到“任務(wù)隊(duì)列”的尾部稼钩。因此,它們實(shí)際上要等到當(dāng)前腳本的所有同步任務(wù)執(zhí)行完达罗,然后再等到本次Event Loop的“任務(wù)隊(duì)列”的所有任務(wù)執(zhí)行完坝撑,才會(huì)開始執(zhí)行。由于前面的任務(wù)到底需要多少時(shí)間執(zhí)行完,是不確定的,所以沒辦法保證锥涕,setTimeout和setInterval指定的任務(wù),一定會(huì)按照預(yù)定時(shí)間執(zhí)行侨拦。
一直有一個(gè)疑問,如果setInterval里面的函數(shù)的執(zhí)行時(shí)間大于設(shè)定的時(shí)間間隔會(huì)怎么樣呢辐宾?
<pre>
setInterval(function(){
console.log(2);
},1000);
(function(){
sleepling(3000);
})();
</pre>
上面的第一行語(yǔ)句要求每隔1000毫秒阳谍,就輸出一個(gè)2。但是螃概,第二行語(yǔ)句需要3000毫秒才能完成,這樣會(huì)發(fā)生的結(jié)果是:等到第二行語(yǔ)句運(yùn)行完成以后鸽疾,立刻連續(xù)輸出三個(gè)2吊洼,然后開始每隔1000毫秒,輸出一個(gè)2制肮。也就是說冒窍,setIntervel具有累積效應(yīng),如果某個(gè)操作特別耗時(shí)豺鼻,超過了setInterval的時(shí)間間隔综液,排在后面的操作會(huì)被累積起來(lái),然后在很短的時(shí)間內(nèi)連續(xù)觸發(fā)儒飒,這可能或造成性能問題谬莹。
參考文章:定時(shí)器
版權(quán)歸王麗峰和饑人谷所有,若有轉(zhuǎn)載桩了,請(qǐng)注明來(lái)源附帽。