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

首頁 > 編程 > JavaScript > 正文

JavaScript 函數節流詳解及方法總結

2019-11-19 17:40:29
字體:
來源:轉載
供稿:網友

JavaScript 函數節流詳解

瀏覽器一個網頁的UI線程只有一個,他同時會處理界面的渲染和頁面JavaScript代碼的執行(簡單擴展一下,瀏覽器或者JavaScript運行大環境并不是單線程,諸如ajax異步回調、hybrid框架內與native通信、事件隊列、CSS運行線程等等都屬于多線程環境,不過ES6引入了Promise類來減少了部分異步情況)。因此當JavaScript代碼運行計算量很大的方法時,就有可能阻塞UI線程,小則導致用戶響應卡頓,嚴重的情況下瀏覽器會提示頁面無響應是否強制關閉。例如網頁的頁面滾動事件、移動設備的滑動、縮放事件等。即使沒有出現嚴重的性能問題,我們也應該站在性能優化的角度將短時間內會多次觸發的大規模處理時間進行分流計算。

如何有效避免UI線程運行過長的代碼,是所有用戶交互應用需要考慮的問題,同樣的問題在客戶端Android可以使用UI主線程開子線程來分散計算。與此對應的,js也可以通過引入webWorker來分散計算,但是在js中有一個更簡單并且效果不錯的方法:函數節流。使用函數節流的核心技巧就是使用定時器分段計算。具體的實現方式大致有兩種思路。

?方法一

1.這種實現方式的思路很好理解:設置一個一間隔時間,比如50毫秒,以此時間為基準設置定時器,當第一次觸發事件到第二次觸發事件間隔小于50毫秒時,清除這個定時器,并設置一個新的定時器,以此類推,直到有一次事件觸發后50毫秒內沒有重復觸發。代碼如下:

function debounce(method){   clearTimeout(method.timer);   method.timer=setTimeout(function(){    method();   },50); } 

這種設計方式有一個問題:本來應該多次觸發的事件,可能最終只會發生一次。具體來說,一個循序漸進的滾動事件,如果用戶滾動太快速,或者程序設置的函數節流間隔時間太長,那么最終滾動事件會呈現為一個很突然的跳躍事件,中間過程都被節流截掉了。這個例子舉的有點夸張了,不過使用這種方式進行節流最終是會明顯感受到程序比不節流的時候“更突兀”,這對于用戶體驗是很差的。有一種彌補這種缺陷的設計思路。

?方法二

2.第二種實現方式的思路與第一種稍有差別:設置一個間隔時間,比如50毫秒,以此時間為基準穩定分隔事件觸發情況,也就是說100毫秒內連續觸發多次事件,也只會按照50毫秒一次穩定分隔執行。代碼如下:

var oldTime=new Date().getTime(); var delay=50; function throttle1(method){   var curTime=new Date().getTime();   if(curTime-oldTime>=delay){    oldTime=curTime;    method();   } } 

相比于第一種方法,第二種方法也許會比第一種方法執行更多次(有時候意味著更多次請求后臺,即更多的流量),但是卻很好的解決了第一種方法清除中間過程的缺陷。因此在具體場景應根據情況擇優決定使用哪種方法。

對于方法二,我們再提供另一種同樣功能的寫法:

var timer=undefined,delay=50; function throttle2(method){   if(timer){     return ;   }   method();   timer=setTimeout(function(){     timer=undefined;   },delay); } 

最后說點個外話,說明一下函數節流的名稱問題,大家往往會看到throttle和debounce兩個方法名,throttle可以譯為“節制,卡住”,debounce可以譯為“防反跳”。在《JavaScript高級程序設計》中作者介紹了方法一,并且作者使用了“throttle”這個函數名。而在《第三方JavaScript編程》書中同時出現了方法一和方法二,作者將方法一命名為“debounce”,將方法二命名為“throttle”。國內在同時介紹兩個方法的時候有些文章錯誤的將方法一命名為“throttle”,而將方法二命名為“debounce”,從英語的角度來說是很不負責任的。因此在這里撥亂反正:方法一適合理解為“防反跳”,應命名為“debounce”;方法二適合理解為“函數節制”,應命名為“throttle”。

感謝閱讀,希望能幫助到大家,謝謝大家對本站的支持!

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 孟津县| 黔西县| 竹溪县| 旬邑县| 犍为县| 辽中县| 谷城县| 宁国市| 资阳市| 宁蒗| 大洼县| 绥化市| 达拉特旗| 从化市| 洪湖市| 饶河县| 时尚| 阳春市| 林口县| 海南省| 屏边| 巴彦县| 宁蒗| 蛟河市| 三台县| 定陶县| 石河子市| 周口市| 石渠县| 罗平县| 托里县| 桑植县| 三原县| 儋州市| 湖口县| 遂川县| 德昌县| 雷山县| 游戏| 奉新县| 南昌县|