iT邦幫忙

2023 iThome 鐵人賽

DAY 22
0
自我挑戰組

前端菜雞_賀周歲成長日誌系列 第 22

節流、比較防抖節流

  • 分享至 

  • xImage
  •  

前言

昨天講了防抖,今天輪到節流。雖然一樣都是為了節省重複執行,但兩者還是有些差異。

最後不免俗地會來個比較。


節流 throttle

目的

限制事件的頻繁觸發。為了解決被觸發太多次事件(例如螢幕滾動事件就會瘋狂觸發)。

用途

用於定期需要執行的事件,以確保在短時間內只觸發一次。例:滾動事件、定時器事件。

效果

使用者頻繁觸發事件,不論被叫了幾次,依然會是在相同的時間間隔,才執行一次事件。觸發一次函式之後,會隔一段時間才能再次執行該函式。

問題解決思路

  • 只在指定的間隔時間會執行事件,其他時候的觸發會被忽略。

實現方法

設置一個計時器,當事件觸發時,如果計時器沒有達到設定的時間間隔,則忽略該事件,否則執行事件處理函數並重置計時器。

假設使用情境

有個很多篇報導的新聞頁,想要用瀑布流的方式載入很多篇新聞,一次顯示八篇,使用者到達頁底時就再載入八篇。(可能偵測到底的時候會一直打function)

function throttle(func, delay) {
  let previousCall = 0; // 記錄上一次函數被呼叫的時間戳
  return function(...args) {
    const currentCall = new Date().getTime();
    if (currentCall - previousCall >= delay) {
      // 如果距離上一次呼叫已經過了指定的延遲時間
      func.apply(this, args);
      previousCall = currentCall;
    }
  };
}

// 範例函數,你可以將需要節流的函數替換成你的實際函數
function exampleFunction() {
  console.log('Function executed.');
	// 呼叫api、實際要執行的動作...
}

// 創建一個節流函數,設置 500 毫秒的延遲
const throttledFunction = throttle(exampleFunction, 500);

以下說明這例

說明

throttle function

  1. previousCall 是用來記錄時間差的變數,前一次呼叫這個函數是什麼時候。
  2. return function(...args){...} 本身是在建立一個用來包裹的函數。
  3. 會return一個值,這個值是函數。
  4. return **function**(...args),這 function 是個匿名函數。
  5. ...args 是ES6的方法中的其餘運算符。用來表示其餘的參數,代表可以傳入不定數量的參數值進入函式,如果沒傳入東西會是空陣列而不是undefined。
  6. {...} 節流函式的判斷主體,用來檢查兩次觸發函式的時間差,有沒有超過 變數delay 指定的時間。

exampleFunction

實際要呼叫api、實際要執行的動作之類的函數。

throttledFunction

呼叫 throttle function 並且設置 delay 時間;在過了 delay 時間,且 throttle function擋掉多餘的觸發後,才會執行 exampleFunction


補充

關於.apply()

.bind()
用於綁定值,作為別的函數要傳入的參數;會有一個新函式產生,因此要直接命名變數成為一函數執行的結果。

.call()
可以用來call一個變數,傳入一個函式。

.apply()
跟.call()相像,只是.apply()傳入參數的形式是array。


兩者比較

共同點

為了避免過多次觸發事件

相異點

防抖:

想要觸發很多次,但只有最後一次成功。

第一次觸發後還是可以一直接受觸發,只是計時器會不停被更新,所以只有最後一次會成功。

節流:

想要觸發很多次,但只有第一次成功。

第一次觸發後就先停止接受觸發,時間過後才可再次觸發,所以時間間隔內,只有第一次會有效。


結語

就是兩招記起來會很好用的方法!

今天就到這,如有說明不周或錯誤的地方,還請多留言討論(鞠躬)。

參考

防抖節流(在二、區別中有張圖,將防抖節流和正常執行表示得很清楚 !)
https://www.readfog.com/a/1634896524109516800
其餘參數(Rest parameters)
https://eyesofkids.gitbooks.io/javascript-start-from-es6/content/part4/rest_spread.html
bind, call, apply 的差異
https://ithelp.ithome.com.tw/m/articles/10260539


上一篇
防抖 - 防抖和節流
下一篇
網頁效能優化的前端方法
系列文
前端菜雞_賀周歲成長日誌31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言