防抖和節流函式是前端常見的效能優化的技巧,透過這兩個函式可以有效的減少函式被觸發的次數,達到效能優化的目的。
防抖函式的作用是在一段時間內只執行一次函式。當多次觸發事件時,防抖函式會在最後一次事件觸發後的一段時間內執行一次函式。如果在這段時間內再次觸發事件,計時器會重新計時。
// This is a JavaScript coding problem from BFE.dev
/**
* @param {(...args: any[]) => any} func
* @param {number} wait
* @returns {(...args: any[]) => any}
*/
function debounce(func, wait) {
// your code here
}
利用計時器 (setTimeout) 來延遲執行目標函式,當 debounce function 被多次觸發時,會不斷清除舊的 timeoutId 並重新計時,直到停止觸發後才執行 func
/**
* @param {(...args: any[]) => any} func 要執行的函式 func
* @param {number} wait 等待時間 (ms)
* @returns {(...args: any[]) => any}
*/
function debounce(func, wait) {
let timeoutId;
return function (...args) {
// 每一次觸發 debounce function 時會清除之前的 timeoutId
if (timeoutId) {
clearTimeout(timeoutId);
}
// 重新計時,設定新的 timeoutId
// 當 wait 時間內沒有再次觸發 debounce function 時,執行 func
timeoutId = setTimeout(() => func(...args), wait);
};
}
節流函式的作用是的作用是在多次觸發事件中,保證函式在固定的時間間隔內只執行一次。當多次觸發事件時,節流函式會在一段時間內執行一次函式 callback。如果在這段時間內再次觸發事件,函式不會被執行,直到這段時間結束。
/**
* @param {(...args:any[]) => any} func 要執行的函式 func
* @param {number} wait 等待時間 (ms)
* @returns {(...args:any[]) => any}
*/
function throttle(func, wait) {
let timer = null;
return function (...args) {
// 如果 timer 存在,表示還在節流等待期間,不執行函式
if (timer) return;
// 設定 timer,等到 wait 時間結束後執行 callback 並清除 timer
timer = setTimeout(() => {
timer = null;
}, wait);
// 時間到,執行 callback 函式
func.apply(this, args);
};
}