萬能的Map以及模糊查詢
阿新 • • 發佈:2022-03-30
前端中的節流防抖應用廣泛也是面試必考的知識點,本文參考網路其他資料對節流防抖機制進行梳理。
是什麼
本質上是優化高頻率執行程式碼的一種手段
如:瀏覽器的 resize
,scroll
,keypress
,mousemove
等事件在觸發時,會不斷地呼叫繫結在事件上的回撥函式,極大地浪費資源,降低前端效能
為了優化體驗,需要對這類事件進行呼叫次數的限制,對此我們就可以採用throttle
(節流)和debounce
(防抖)的方式來減少呼叫頻率
- 防抖: n 秒後再執行該事件,若在 n 秒內被重複觸發,則重新計時
- 節流: n 秒內只執行一次,若在 n 秒內重複觸發,只有一次生效
節流實現
節流函式相對簡單,本質上就是利用閉包儲存標記在預設的時間內阻塞新事件的執行。
const throttle = (fn, delay = 500) => {
let valid = true; //使用閉包儲存標記
return (...args) => {
if (!valid) return; //valid為false時會一直阻塞事件,直到定時器把valid改為true
valid = false;
setTimeout(() => {
fn(...args)
valid = true;
}, delay);
};
};
防抖實現
防抖函式同樣是利用閉包,在預設時間內如果重複觸發事件就清除定時器並重新計時。
const debounce = (fn, delay = 500) => {
let timeout;
return (...args) => {
if (timeout) {
clearTimeout(timeout); // 預設時間內重複執行就清除之前的計時器
}
timeout = setTimeout(() => {
fn(...args);
}, delay);
};
};
進一步思考,如果需要觸發事件時就立即執行該怎麼辦
const debounce = (fn, delay = 500, isImmediate) => { let timeout; return (...args) => { // 判斷是否立即執行 if (!timeout && isImmediate) { fn(...args); } clearTimeout(timeout); timeout = setTimeout(() => { if (!isImmediate) { fn(...args); } timeout = null; }, delay); }; };