1. 程式人生 > 其它 >萬能的Map以及模糊查詢

萬能的Map以及模糊查詢

前端中的節流防抖應用廣泛也是面試必考的知識點,本文參考網路其他資料對節流防抖機制進行梳理。

是什麼

本質上是優化高頻率執行程式碼的一種手段

如:瀏覽器的 resizescrollkeypressmousemove 等事件在觸發時,會不斷地呼叫繫結在事件上的回撥函式,極大地浪費資源,降低前端效能

為了優化體驗,需要對這類事件進行呼叫次數的限制,對此我們就可以採用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);
  };
};