国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > JavaScript > 正文

淺談對于“不用setInterval,用setTimeout”的理解

2019-11-19 10:56:56
字體:
來源:轉載
供稿:網友

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

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

關于時間間隔,紅寶書中這么說:

設定一個 150ms 后執行的定時器不代表到了 150ms 代碼就立刻執行,它表示代碼會在 150ms 后被加入到隊列中。如果在這個時間點上,隊列中沒有其他東西,那么這段代碼就會被執行。

對于這個時間間隔的理解非常重要!步入正題,為何不用setInterval,因為它可能會帶來兩個問題:

  • “丟幀”現象
  • 不同定時器的代碼的執行間隔比預期小

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

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

在1.7s處,func1在執行,func2在隊列里等待執行,func2就是該定時器的代碼實例,按照JS引擎的處理,func3不會加入到事件隊列里,更別說執行了,這就導致出現了“丟幀”現象。而在圖中也可以注意到,func1執行完畢,線程空閑了,func2就可以執行了,這就使得func1和func2之間的執行沒有時間間隔,這跟我們所預期的500ms產生一次結果是不同的。

而如果使用鏈式setTimeout調用,每次函數執行的時候都會創建一個新的定時器。第二個setTimeout()調用使用了 arguments.callee 來獲取對當前執行的函數的引用,并為其設置另外一個定時器。這樣做的好處是,在前一個定時器代碼執行完之前,不會向隊列插入新的定時器代碼,確保不會有任何缺失的間隔。而且,它可以保證在下一次定時器代碼執行之前,至少要等待指定的間隔,避免了連續的運行。代碼如下所示

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

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

通過上面這個場景,我們能知道當需要用定時器來設置一個操作重復執行,并且這個操作需要執行一定的時間,記得用setTimeout,不用setInterval!

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持武林網。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 蒙自县| 罗城| 南投县| 航空| 郎溪县| 逊克县| 崇州市| 望谟县| 平潭县| 调兵山市| 遵化市| 茌平县| 商南县| 新闻| 六盘水市| 深州市| 东乡| 志丹县| 苍南县| 朔州市| 堆龙德庆县| 新巴尔虎左旗| 镇江市| 德安县| 来宾市| 准格尔旗| 板桥市| 博兴县| 开阳县| 通道| 策勒县| 安康市| 汉阴县| 赫章县| 汨罗市| 芦溪县| 错那县| 嵊州市| 大关县| 琼中| 乐东|