亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

淺談對(duì)于“不用setInterval,用setTimeout”的理解

 更新時(shí)間:2019年08月28日 09:33:37   作者:小利子  
這篇文章主要介紹了淺談對(duì)于“不用setInterval,用setTimeout”的理解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

JavaScript高級(jí)程序設(shè)計(jì)(第三版)(以下簡稱紅寶書)22.3高級(jí)定時(shí)器中詳細(xì)介紹了定時(shí)器setTimeout和setInterval,看完書后,深入理解了二者的區(qū)別,結(jié)合前輩們給我的建議“用setTimeout,不要用setInterval”,寫下此文,分析這個(gè)建議的合理性。
這兩個(gè)家伙看上去長得差不多,func是要執(zhí)行的函數(shù),interval是時(shí)間間隔。

setTimeout(func,interval)
setInterval(func,interval)

關(guān)于時(shí)間間隔,紅寶書中這么說:

設(shè)定一個(gè) 150ms 后執(zhí)行的定時(shí)器不代表到了 150ms 代碼就立刻執(zhí)行,它表示代碼會(huì)在 150ms 后被加入到隊(duì)列中。如果在這個(gè)時(shí)間點(diǎn)上,隊(duì)列中沒有其他東西,那么這段代碼就會(huì)被執(zhí)行。

對(duì)于這個(gè)時(shí)間間隔的理解非常重要!步入正題,為何不用setInterval,因?yàn)樗赡軙?huì)帶來兩個(gè)問題:

  • “丟幀”現(xiàn)象
  • 不同定時(shí)器的代碼的執(zhí)行間隔比預(yù)期小

一圖勝千言,如下圖所示,讓我們跟著時(shí)間線看看這樣的問題怎么發(fā)生的。假定一個(gè)場景,在click事件中設(shè)置了setInterval(func,500),假設(shè)click事件和定時(shí)器內(nèi)函數(shù)的執(zhí)行時(shí)間都是1s,為了方便陳述,我把不同時(shí)間觸發(fā)的func取了不同的名字,實(shí)際上接下來的func1=func2=func3=func。在0s處觸發(fā)click事件,click事件執(zhí)行,在0.2s處觸發(fā)定時(shí)器,0.7s處第一個(gè)函數(shù)func1加入到事件隊(duì)列,但由于JS引擎是單線程的,click事件還在執(zhí)行,所以func1等待著,等到1s處,click事件執(zhí)行完畢,fun1才開始執(zhí)行。按照定時(shí)器的時(shí)間間隔,1.2s處第二個(gè)函數(shù)func2加入到事件隊(duì)列,但此時(shí)fun1正在執(zhí)行,所以func2只能等待。0.5s后,也就是1.7s處,第三個(gè)函數(shù)func理應(yīng)加入事件隊(duì)列,但是JS引擎做了一個(gè)事情:

當(dāng)使用 set Interval()時(shí),僅當(dāng)沒有該定時(shí)器的任何其他代碼實(shí)例時(shí),才將定時(shí)器代碼添加到隊(duì)列中。

在1.7s處,func1在執(zhí)行,func2在隊(duì)列里等待執(zhí)行,func2就是該定時(shí)器的代碼實(shí)例,按照J(rèn)S引擎的處理,func3不會(huì)加入到事件隊(duì)列里,更別說執(zhí)行了,這就導(dǎo)致出現(xiàn)了“丟幀”現(xiàn)象。而在圖中也可以注意到,func1執(zhí)行完畢,線程空閑了,func2就可以執(zhí)行了,這就使得func1和func2之間的執(zhí)行沒有時(shí)間間隔,這跟我們所預(yù)期的500ms產(chǎn)生一次結(jié)果是不同的。

而如果使用鏈?zhǔn)絪etTimeout調(diào)用,每次函數(shù)執(zhí)行的時(shí)候都會(huì)創(chuàng)建一個(gè)新的定時(shí)器。第二個(gè)setTimeout()調(diào)用使用了 arguments.callee 來獲取對(duì)當(dāng)前執(zhí)行的函數(shù)的引用,并為其設(shè)置另外一個(gè)定時(shí)器。這樣做的好處是,在前一個(gè)定時(shí)器代碼執(zhí)行完之前,不會(huì)向隊(duì)列插入新的定時(shí)器代碼,確保不會(huì)有任何缺失的間隔。而且,它可以保證在下一次定時(shí)器代碼執(zhí)行之前,至少要等待指定的間隔,避免了連續(xù)的運(yùn)行。代碼如下所示

setTimeout(function(){
  //do something
  setTimeout(arguments.callee,interval);
},interval)

用setTimeout方法的話,上面假設(shè)的場景就發(fā)生了改變,如下圖所示,在0s處觸發(fā)click事件,click事件執(zhí)行,在0.2s處觸發(fā)定時(shí)器,0.7s處第一個(gè)函數(shù)func1加入到事件隊(duì)列,click事件執(zhí)行了1s,在1s處func1執(zhí)行,2s處func1執(zhí)行結(jié)束,第二個(gè)setTimeout定時(shí)器才被觸發(fā),0.5s后將函數(shù)func2加入隊(duì)列,此時(shí)隊(duì)列為空,func2開始執(zhí)行,3.5s處func2執(zhí)行結(jié)束,又一個(gè)setTimeout定時(shí)器被觸發(fā),0.5s后將函數(shù)func3加入隊(duì)列,此時(shí)隊(duì)列為空,func3開始執(zhí)行。。。

通過上面這個(gè)場景,我們能知道當(dāng)需要用定時(shí)器來設(shè)置一個(gè)操作重復(fù)執(zhí)行,并且這個(gè)操作需要執(zhí)行一定的時(shí)間,記得用setTimeout,不用setInterval!

以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

最新評(píng)論