深入理解函式節流與函式防抖

mylittleZ發表於2019-03-10

在人生的第一個面試,第一個問題就是面試官問專案遇到的難點以及怎麼解決的。我說了自己是如何處理函式節流,結果說的並不是很滿意。所以,我決定重新總結一下函式節流與防抖。

深入理解概念

throttle-函式節流:我們希望函式在以一個可以接受的頻率重複呼叫,從而減少函式的執行頻率提高網頁效能。

debounce-函式防抖:我們希望函式只會呼叫一次,即使在這之前反覆呼叫它,最終也只呼叫一次。

下面我們來看一個栗子...

  
  // 普通滾動
	document.getElementById("noscroll").onscroll = function(){
	console.log("普通滾動");
	};

複製程式碼

除了滾動事件此類問題還有:

1.resize監聽瀏覽器視窗大小 2. 滑鼠的點選事件 mouseup, mousedown,mousemove 3.鍵盤的keyup, keydown, input事件
複製程式碼

函式防抖原理

如果方法多次被觸發,則把上次記錄的延遲執行程式碼用clearTimeout清掉,重新開始。如果計時完畢,沒有方法進來訪問觸發,則執行程式碼。

這個方法的作用是監聽ID為debounce元素的滾動事件 進入滾動事件方法體的時候,做的第一件事就是清除上次未執行的setTimeout。而setTimeout的引用id由變數timer記錄。

所以這裡直接執行clearTimeout即可。 然後,將需要執行的程式碼放入setTimeout中,再返回setTimeout引用給timer快取。 如果倒數計時300ms以後,還沒有新的方法觸發滾動事件,則執行setTimeout中的程式碼。

函式防抖的實現重點,就是巧用setTimeout做快取池,而且可以輕易地清除待執行的程式碼。

下面是函式防抖程式碼

	// 函式防抖
	var timer = false;
	document.getElementById("debounce").onscroll = function(){
	clearTimeout(timer); // 每次呼叫滾動事件都會將前一次的timer清空,確保只執行一次

	timer = setTimeout(function(){
	console.log("函式防抖");
	}, 300);
	};			
}

複製程式碼

函式防抖的應用場景:最常見的是使用者註冊時候的手機號碼驗證和郵箱驗證。只有等使用者輸入完畢後,才需要檢查格式是否正確,如果不正確,再彈出提示語。

函式節流原理

// 函式節流
var timer = true;
document.getElementById("throttle").onscroll = function(){
    if(!timer){
        // 判斷是否已空閒
        //程式碼進行到這兒則是在執行中,則直接return
        return;
    }

   timer = false;
    setTimeout(function(){
        console.log("函式節流");
        timer = true;
    }, 300);
};
複製程式碼

函式節流的要點是,宣告一個變數(timer)當標誌位,記錄當前程式碼是否在執行。如果空閒(即timer為true),則可以正常觸發方法執行。如果程式碼正在執行,則取消這次方法執行,直接return,這樣就可以做到函式減少執行頻率。

相關文章