JavaScript中函式防抖、節流

Echoyya、發表於2021-03-26

碼文不易,轉載請帶上本文連結,感謝~ https://www.cnblogs.com/echoyya/p/14565642.html


函式節流和函式防抖,兩者都是優化高頻率執行js程式碼的一種手段。

以監聽頁面滾動為例,分別看一下普通滾動函式節流函式防抖三者的實現效果。

函式節流

函式節流:是指在高頻事件觸發期間,n秒內函式只會執行一次。

  • 比如人眨眼睛,就是一定時間內眨一次。
  • 再比如就是遊戲中的技能CD,按下技能以後,再規定的時間內,你再按也沒用,只能冷卻好了再按。

使用場景:clickonMouseOveronMouseMoveresizeinputscroll

// 函式防抖
var timer = false;
document.getElementById("debounce").onscroll = function(){
	clearTimeout(timer); // 清除未執行的程式碼,重置回初始化狀態

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

函式防抖的要點:也需要一個定時器來輔助實現程式碼延遲執行。如果計時未完之前,方法被多次觸發,則清除上次記錄的定時器標記,重新開始。若計時完畢,沒有繼續觸發方法,則執行邏輯程式碼。

  1. 監聽id = debounce元素的滾動事件,首先就是清除上次未執行的setTimeout的引用timer

  2. clearTimeout方法,允許傳入無效的值。所以直接執行clearTimeout即可。

  3. 將需要執行的程式碼放入setTimeout定時器中,再返回定時器引用給timer快取。

  4. 如果倒數計時結束,沒有新的方法觸發滾動事件,則執行setTimeout中的程式碼。

  5. 函式防抖的原理,就是巧用setTimeout做快取池,並且可以輕易地清除待執行程式碼。

函式防抖

函式防抖:是指觸發高頻事件n秒後函式會執行一次,如果n秒內高頻事件被再次觸發,則重新計算時間;在整個過程中,事件函式只會被執行一次。

  • 比如坐公交,在一定時間內,如果有人陸續刷卡上車,司機就不會開車。只有沒有人再刷卡了,司機才開車。
  • 再比如遊戲中的buff,吃了bull,開始倒數計時,此時又吃了一個buff,則重新記時。

使用場景:clickonMouseOveronMouseMoveresizeinputscroll

// 函式節流
var canRun = true;
document.getElementById("throttle").onscroll = function(){
	if(!canRun){
		// 判斷是否已空閒,如果在執行中,則直接return
		return;
	}

	canRun = false;
	setTimeout(function(){
		console.log("函式節流");
		canRun = true;
	}, 1000);
}

函式節流的要點:宣告一個標誌位,設定執行的時間間隔,記錄當前程式碼是否在執行,如果空閒,則可以正常觸發方法執行,反之則取消這次方法執行,直接return

  1. 監聽id = throttle元素的滾動事件。當canRuntrue,代表當前滾動處理事件是空閒的,可以使用。然後下一步的操作就是canRun=false。這樣其他請求執行滾動事件的方法,就被return。

  2. setTimeout設定1000ms時間間隔,執行定時器中的回撥函式,釋放標誌位,允許執行下一次滾動事件。

  3. 若具體執行的方法是一個回撥函式,也可以將canRun=true放到callback中。只要理解了函式節流基本原理,改造就會得心應手。

相關文章