自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

高頻:手寫一個節(jié)流函數(shù) Throttle

開發(fā) 前端
比如綁定響應(yīng)鼠標移動、窗口大小調(diào)整、滾屏等事件時,綁定的函數(shù)觸發(fā)的頻率會很頻繁。若稍處理函數(shù)微復(fù)雜,需要較多的運算執(zhí)行時間和資源,往往會出現(xiàn)延遲,甚至導(dǎo)致假死或者卡頓感。為了優(yōu)化性能,這時就很有必要使用 debounce 或 throttle 了。

[[438987]]

debounce 與 throttle 是開發(fā)中常用的高階函數(shù),作用都是為了防止函數(shù)被高頻調(diào)用,換句話說就是,用來控制某個函數(shù)在一定時間內(nèi)執(zhí)行多少次。

使用場景

比如綁定響應(yīng)鼠標移動、窗口大小調(diào)整、滾屏等事件時,綁定的函數(shù)觸發(fā)的頻率會很頻繁。若稍處理函數(shù)微復(fù)雜,需要較多的運算執(zhí)行時間和資源,往往會出現(xiàn)延遲,甚至導(dǎo)致假死或者卡頓感。為了優(yōu)化性能,這時就很有必要使用 debounce 或 throttle 了。

debounce 與 throttle 區(qū)別

防抖 (debounce) :多次觸發(fā),只在最后一次觸發(fā)時,執(zhí)行目標函數(shù)。

節(jié)流(throttle):限制目標函數(shù)調(diào)用的頻率,比如:1s內(nèi)不能調(diào)用2次。

手寫一個 throttle

實現(xiàn)方案有以下兩種:

  • 第一種是用時間戳來判斷是否已到執(zhí)行時間,記錄上次執(zhí)行的時間戳,然后每次觸發(fā)事件執(zhí)行回調(diào),回調(diào)中判斷當前時間戳距離上次執(zhí)行時間戳的間隔是否已經(jīng)達到時間差(Xms) ,如果是則執(zhí)行,并更新上次執(zhí)行的時間戳,如此循環(huán)。
  • 第二種方法是使用定時器,比如當 scroll 事件剛觸發(fā)時,打印一個 hello world,然后設(shè)置個 1000ms 的定時器,此后每次觸發(fā) scroll 事件觸發(fā)回調(diào),如果已經(jīng)存在定時器,則回調(diào)不執(zhí)行方法,直到定時器觸發(fā),handler 被清除,然后重新設(shè)置定時器。

這里我們采用第一種方案來實現(xiàn),通過閉包保存一個 previous 變量,每次觸發(fā) throttle 函數(shù)時判斷當前時間和 previous 的時間差,如果這段時間差小于等待時間,那就忽略本次事件觸發(fā)。如果大于等待時間就把 previous 設(shè)置為當前時間并執(zhí)行函數(shù) fn。

我們來一步步實現(xiàn),首先實現(xiàn)用閉包保存 previous 變量。

  1. const throttle = (fn, wait) => { 
  2.  // 上一次執(zhí)行該函數(shù)的時間 
  3.   let previous = 0 
  4.   return function(...args) { 
  5.     console.log(previous) 
  6.     ... 
  7.   } 

執(zhí)行 throttle 函數(shù)后會返回一個新的 function ,我們命名為 betterFn 。

  1. const betterFn = function(...args) { 
  2.   console.log(previous) 
  3.     ... 

betterFn 函數(shù)中可以獲取到 previous 變量值也可以修改,在回調(diào)監(jiān)聽或事件觸發(fā)時就會執(zhí)行 betterFn ,即 betterFn(),所以在這個新函數(shù)內(nèi)判斷當前時間和 previous 的時間差即可。

  1. const betterFn = function(...args) { 
  2.   let now = +new Date(); 
  3.   if (now - previous > wait) { 
  4.     previous = now 
  5.     // 執(zhí)行 fn 函數(shù) 
  6.     fn.apply(this, args) 
  7.   } 

結(jié)合上面兩段代碼就實現(xiàn)了節(jié)流函數(shù),所以完整的實現(xiàn)如下。

  1. // fn 是需要執(zhí)行的函數(shù) 
  2. // wait 是時間間隔 
  3. const throttle = (fn, wait = 50) => { 
  4.   // 上一次執(zhí)行 fn 的時間 
  5.   let previous = 0 
  6.   // 將 throttle 處理結(jié)果當作函數(shù)返回 
  7.   return function(...args) { 
  8.     // 獲取當前時間,轉(zhuǎn)換成時間戳,單位毫秒 
  9.     let now = +new Date() 
  10.     // 將當前時間和上一次執(zhí)行函數(shù)的時間進行對比 
  11.     // 大于等待時間就把 previous 設(shè)置為當前時間并執(zhí)行函數(shù) fn 
  12.     if (now - previous > wait) { 
  13.       previous = now 
  14.       fn.apply(this, args) 
  15.     } 
  16.   } 
  17.  
  18. // DEMO 
  19. // 執(zhí)行 throttle 函數(shù)返回新函數(shù) 
  20. const betterFn = throttle(() => console.log('fn 函數(shù)執(zhí)行了'), 1000) 
  21. // 每 10 毫秒執(zhí)行一次 betterFn 函數(shù),但是只有時間差大于 1000 時才會執(zhí)行 fn 
  22. setInterval(betterFn, 10) 

 

責(zé)任編輯:武曉燕 來源: 三分鐘學(xué)前端
相關(guān)推薦

2021-12-09 10:57:19

防抖函數(shù) Debounce

2016-06-30 10:24:47

JavaScript節(jié)流Throttle

2022-03-09 09:43:01

工具類線程項目

2020-11-02 08:19:18

RPC框架Java

2021-03-18 08:04:54

AQS工具CAS

2022-01-26 15:20:00

配置微服務(wù)架構(gòu)

2022-10-31 08:27:53

Database數(shù)據(jù)數(shù)據(jù)庫

2021-02-22 17:17:38

Proxy緩存代碼

2017-03-02 13:31:02

監(jiān)控系統(tǒng)

2020-09-27 14:13:50

Spring BootJava框架

2024-08-02 09:49:35

Spring流程Tomcat

2024-03-08 08:26:20

防抖節(jié)流delay?

2022-05-17 20:37:41

MyPick泛型對象類型

2020-12-13 11:57:57

Nodejs微信開發(fā)

2021-02-20 09:45:02

RPC框架Java

2022-01-17 11:50:38

Linux CPULinux 系統(tǒng)

2020-04-20 09:02:33

函數(shù)RPCCPU

2021-02-21 09:25:41

開源技術(shù) 工具

2023-10-16 22:03:36

日志包多線程日志包

2015-06-02 10:24:43

iOS網(wǎng)絡(luò)請求降低耦合
點贊
收藏

51CTO技術(shù)棧公眾號