91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

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

發布時間:2020-09-01 13:31:06 來源:腳本之家 閱讀:175 作者:小利子 欄目:web開發

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產生一次結果是不同的。

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

而如果使用鏈式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開始執行。。。

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

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

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

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

阿克| 体育| 望谟县| 英德市| 呼和浩特市| 应城市| 伊宁市| 宣威市| 铜川市| 通江县| 江津市| 仙桃市| 海城市| 喀什市| 古田县| 饶阳县| 宁明县| 华坪县| 兰西县| 陆川县| 普兰店市| 北碚区| 马鞍山市| 五原县| 加查县| 洪洞县| 沁阳市| 贵港市| 华阴市| 梁河县| 元阳县| 望城县| 若尔盖县| SHOW| 星座| 沙湾县| 平凉市| 洛浦县| 格尔木市| 精河县| 灵宝市|