throttle跟 debounce有什麼區別?

Steven Chen
Sep 1, 2020

--

「Photo by Chromatograph on Unsplash

自從我去年在寫 scroll event監聽的時候接觸到了 throttle / debounce,就一直搞不懂這兩個概念之間的差別。
直到最近看了網路上對他們各自的使用場景分享,我對這兩個概念才有了新的領悟。
於是我決定把自己的想法寫下來。

名詞對照:

throttle(節流): 從最初一次觸發開始,在 t秒後執行函數。中間無論觸發多少次都不會執行。
debounce(防抖): 從最後一次觸發開始,在 t秒後執行函數。因為是最後一次觸發,所以會把中間的觸發蓋掉。
觸發: 函數被呼叫的動作。執行: 函數被執行的動作。delay(延遲): 在下文中以 t秒代替。

「第一次延後執行」的 throttle

第一次立刻執行的 throttle留待後面討論。

可以自己在 console裡面試試看

throttle的特色在於用 isClose來控制閥門(valve)的開關 — 決定這次的觸發會不會被承認。

使用場景: 控制 scroll event callback的觸發次數,讓 callback不要太頻繁被觸發。
觸發了好幾次,但是只有最初那次被執行

debounce

可以自己在 console裡面試試看

debounce跟 throttle相比之下,少了 isClose來控制閥門 — 因為 debounce只承認最後一次觸發。

debounce與 throttle的比較
使用場景: 搜尋輸入框的推薦關鍵字功能,節約查詢推薦關鍵字動作的觸發次數。
觸發了好幾次,但是只有最後那次被執行

如果用 debounce來控制 scroll event callback會發生什麼事?

因為 debounce只會執行最後一次呼叫的 callback ,所以要等到頁面不再滾動後 t秒才會執行最後一次滾動的 event。
在這之前不管你怎麼滾動,都不會觸發任何 callback。
就像拿著拍子不斷地把乒乓球拍上去,球一直不會落地。
使用體驗就會卡卡的。

如果用 throttle來控制搜尋輸入框的推薦關鍵字功能會發生什麼事?

假如你本來打了 apple、馬上改成了 book,接著又立刻改成了 cookie。
你的推薦關鍵字會一直停在 apple。因為當你輸入 apple後,有 t秒的時間都不會再執行查詢推薦關鍵字的動作了。

「第一次立刻執行」的 throttle

只要把 func.apply(this, args)移出 setTimeout的 function就行了

第一次延後執行與第一次立刻執行
先執行第一次,再關上閥門

總結:

  1. throttle(節流): 從最初一次觸發開始,在 t秒後執行函數。中間無論觸發多少次都不會執行。
  2. debounce(防抖): 從最後一次觸發開始,在 t秒後執行函數。因為是最後一次觸發,所以會把中間的觸發蓋掉。
  3. throttle適合用來讓某個動作每隔一段期間才能被執行一次。
  4. debounce適合用來讓某個動作的執行不斷地延後,直到觸發與執行的間隔超過延遲時間。
  5. throttle與 debounce是有差別的,在使用前要仔細考慮。

--

--