系統(tǒng)理解 setTimeout()和 setInterval()

今天剛好在看setTimeout()的一個(gè)案例,在案例的解析中提到了setTimeout()和setInterval()的使用區(qū)別,但是比較理論,所以

決定自己也總結(jié)一下,寫(xiě)寫(xiě)例子幫助理解一下。

? ? ? ?首先是說(shuō)說(shuō)這兩個(gè)方法的具體時(shí)如何使用的。

1、setTimeout()方法

? ? ? 這個(gè)方法所有瀏覽器都支持,setTimeout( ) 是屬于 window 的 method, 但我們都是略去 window 這頂層物件名稱, 這是用來(lái)

設(shè)定一個(gè)時(shí)間, 時(shí)間到了, 就會(huì)執(zhí)行一個(gè)指定的 method。

? ? ? 定義和用法: setTimeout()方法用于在指定的毫秒數(shù)后調(diào)用函數(shù)或計(jì)算表達(dá)式。

? ? ? 語(yǔ)法: setTimeout(code,millisec)

? ? ? 參數(shù): code (必需):要調(diào)用的函數(shù)后要執(zhí)行的 JavaScript 代碼串。millisec(必需):在執(zhí)行代碼前需等待的毫秒數(shù)。  ?

?提示: setTimeout() 只執(zhí)行 code 一次。如果要多次調(diào)用,請(qǐng)使用 setInterval() 或者讓 code 自身再次調(diào)用 setTimeout()(即利用遞歸)。

? ? ? 看完了基本的語(yǔ)法,接下來(lái)我寫(xiě)一個(gè)很簡(jiǎn)單的例子說(shuō)明這個(gè)的使用方法。

代碼如下:

<!DOCTYPE html>

setTimeout()使用

請(qǐng)等待三秒!

setTimeout("alert('終于等到你了!')",3000)

? ? ? 當(dāng)我們打開(kāi)網(wǎng)頁(yè)3秒時(shí),就會(huì)彈出一個(gè)框。但是,只會(huì)彈出一次,因?yàn)?setTimeout()不會(huì)自動(dòng)重復(fù)執(zhí)行,是在載入后的延遲指定

時(shí)間去執(zhí)行一次表達(dá)式。

當(dāng)然,我們也可以讓setTimeout()執(zhí)行函數(shù),而且可以重復(fù)執(zhí)行多次(利用遞歸),而不是一次。

代碼如下:

<!DOCTYPE html>

varx =0;

functioncountSecond()

? ? ? ? {

x = x+1;

document.haorooms.haoroomsinput.value = x;

setTimeout("countSecond()",1000)

? ? ? ? }

? ? countSecond();

? ? ? ?實(shí)現(xiàn)的方法就是讓函數(shù)自身反復(fù)調(diào)用。

2、setInterval()方法

setInterval() 方法可按照指定的周期(以毫秒計(jì))來(lái)調(diào)用函數(shù)或計(jì)算表達(dá)式。setInterval() 方法會(huì)不停地調(diào)用函數(shù),直到?

clearInterval() 被調(diào)用或窗口被關(guān)閉。由 setInterval() 返回的 ID 值可用作 clearInterval() 方法的參數(shù)。

語(yǔ)法: setInterval(code,millisec[,"lang"])

? ? ?參數(shù): code 必需。要調(diào)用的函數(shù)或要執(zhí)行的代碼串。millisec 必須。周期性執(zhí)行或調(diào)用 code 之間的時(shí)間間隔,以毫秒計(jì)。

返回值: 一個(gè)可以傳遞給 Window.clearInterval() 從而取消對(duì) code 的周期性執(zhí)行的值。

? ? ?如果我們想要每隔3秒就彈出一個(gè)框要如何實(shí)現(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() 從載入后,每隔指定的時(shí)間就執(zhí)行一次表達(dá)式。

3、區(qū)別

? ? ?通過(guò)上面可以看出,setTimeout和setinterval的最主要區(qū)別是:

? ? 1)setTimeout只運(yùn)行一次,也就是說(shuō)設(shè)定的時(shí)間到后就觸發(fā)運(yùn)行指定代碼,運(yùn)行完后即結(jié)束。如果運(yùn)行的代碼中再次運(yùn)行同樣

的setTimeout命令,則可循環(huán)運(yùn)行。(即 要循環(huán)運(yùn)行,需函數(shù)自身再次調(diào)用 setTimeout());而 setinterval是循環(huán)運(yùn)行的,即每

到設(shè)定時(shí)間間隔就觸發(fā)指定代碼。這是真正的定時(shí)器。

? ? 2)setinterval使用簡(jiǎn)單,而setTimeout則比較靈活,可以隨時(shí)退出循環(huán),而且可以設(shè)置為按不固定的時(shí)間間隔來(lái)運(yùn)行,比如第

一次1秒,第二次2秒,第三次3秒。


值得注意的是:

setTimeout(function(){

? ? console.log(1);

});

console.log(0);

這里,實(shí)際上,把setTimeout的第二個(gè)參數(shù)設(shè)置為0s,并不是立即執(zhí)行函數(shù)的意思,只是把函數(shù)放入異步隊(duì)列。瀏覽器先執(zhí)行完同步隊(duì)列里的任務(wù),才會(huì)去執(zhí)行異步隊(duì)列中的任務(wù)。

setInterval()原理與setTimeout(),也是講代碼放入異步隊(duì)列中。但是,setInterval()存在一個(gè)問(wèn)題,

使用setInterval()的問(wèn)題在于,定時(shí)器代碼可能在代碼再次被添加到隊(duì)列之前還沒(méi)有完成執(zhí)行,結(jié)果導(dǎo)致定時(shí)器代碼連續(xù)運(yùn)行好幾次,而之間沒(méi)有任何停頓。而javascript引擎對(duì)這個(gè)問(wèn)題的解決是:當(dāng)使用setInterval()時(shí),僅當(dāng)沒(méi)有該定時(shí)器的任何其他代碼實(shí)例時(shí),才將定時(shí)器代碼添加到隊(duì)列中。這確保了定時(shí)器代碼加入到隊(duì)列中的最小時(shí)間間隔為指定間隔。

  但是,這樣會(huì)導(dǎo)致兩個(gè)問(wèn)題:1、某些間隔被跳過(guò);2、多個(gè)定時(shí)器的代碼執(zhí)行之間的間隔可能比預(yù)期的小。



兩者的工作原理:大家都知道,JavaScript是單線程執(zhí)行的,setTimeout和setInterval執(zhí)行原理其實(shí)也很簡(jiǎn)單。

setTimeout會(huì)在調(diào)用后的millisec時(shí)間間隔后往事件隊(duì)列里添加回調(diào)函數(shù),然后等待執(zhí)行。?

setInterval會(huì)按照第二個(gè)參數(shù)的周期時(shí)間周期性的往事件隊(duì)列添加回調(diào)函數(shù),然后等待執(zhí)行,這里的一個(gè)注意點(diǎn)是如果事件隊(duì)列里的回調(diào)函數(shù)還沒(méi)有執(zhí)行,不會(huì)重復(fù)添加。

注:html5規(guī)定setTimeout和setInterval的延遲時(shí)間最少為4ms. 所以setTimeout(function(){},0)其實(shí)是setTimeout(function(){}, 4)。


如果上面代碼中的onclick事件處理程序執(zhí)行了300ms,那么定時(shí)器的代碼至少要在定時(shí)器設(shè)置之后的300ms后才會(huì)被執(zhí)行。隊(duì)列中所有的代碼都要等到j(luò)avascript進(jìn)程空閑之后才能執(zhí)行,而不管它們是如何添加到隊(duì)列中的。如下圖:


 如圖所示,盡管在255ms處添加了定時(shí)器代碼,但這時(shí)候還不能執(zhí)行,因?yàn)閛nclick事件處理程序仍在運(yùn)行。定時(shí)器代碼最早能執(zhí)行的時(shí)機(jī)是在300ms處,即onclick事件處理程序結(jié)束之后。



實(shí)際上,把setTimeout的第二個(gè)參數(shù)設(shè)置為0s,并不是立即執(zhí)行函數(shù)的意思,只是把函數(shù)放入異步隊(duì)列。瀏覽器先執(zhí)行完同步隊(duì)列里的任務(wù),才會(huì)去執(zhí)行異步隊(duì)列中的任務(wù)。


驗(yàn)證例子:

例一:

<!DOCTYPE html>

<html>

<head>

<meta charset="utf-8">

<title>菜鳥(niǎo)教程(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>我的第一個(gè) JavaScript 程序</h1>

<p id="demo">這是一個(gè)段落</p>

<button type="button" onclick="displayDate()">顯示日期</button>

</body>

</html>

此代碼結(jié)果顯示先后順序:

1(1s)、2(2s)、1233131123(2.5s)、3(3s)、4(4s)........

原理分析:


例二:

<!DOCTYPE html>

<html>

<head>

<meta charset="utf-8">

<title>菜鳥(niǎo)教程(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>我的第一個(gè) JavaScript 程序</h1>

<p id="demo">這是一個(gè)段落</p>

<button type="button" onclick="displayDate()">顯示日期</button>

</body>

</html>

效果及分析:


最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • ??JavaScript 是一種極其靈活的語(yǔ)言,具有多種使用風(fēng)格。 ??一般來(lái)說(shuō),編寫(xiě) JavaScript 要么...
    霜天曉閱讀 829評(píng)論 0 0
  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,534評(píng)論 19 139
  • 弄懂js異步 講異步之前,我們必須掌握一個(gè)基礎(chǔ)知識(shí)-event-loop。 我們知道JavaScript的一大特點(diǎn)...
    DCbryant閱讀 2,875評(píng)論 0 5
  • 文/小葉 白茶功效:因富含氨基酸,酚氨比值較小(茶多酚為茶苦澀因素,氨基酸則主導(dǎo)甜度),所以口感為清甜潤(rùn)滑。降三高...
    博土閱讀 2,121評(píng)論 7 1
  • 硝煙彌漫的戰(zhàn)場(chǎng) 本不該出現(xiàn)的一刻寧?kù)o 意外卻遇見(jiàn)了你 一架會(huì)彈奏風(fēng)暴的鋼琴 我試著撥動(dòng)你的琴鍵 原諒那來(lái)自門(mén)外漢的...
    簡(jiǎn)村小吹閱讀 282評(píng)論 11 13

友情鏈接更多精彩內(nèi)容