前端工具包之防抖函數

前言

咱們在開發過程當中,總會封裝一些公共函數來做爲咱們的工具來簡化代碼或者複用代碼,爲此,我打算整理一下我平常工做中經常使用的一些封裝的工具函數,本篇文章爲防抖函數的相關封裝前端

系列文章

1.前端工具包之深淺拷貝git

2.前端工具包之日期格式化web

3.前端工具包之防抖函數緩存

4.前端工具包之小工具bash

5.前端工具包之log美化app

背景

咱們在平常開發中常常會遇到一個需求,好比在滾動事件中須要作個複雜計算或者實現一個按鈕的防二次點擊操做。ide

這些需求均可以經過函數防抖動來實現。尤爲是第一個需求,若是在頻繁的事件回調中作複雜計算,頗有可能致使頁面卡頓,不如將屢次計算合併爲一次計算,只在一個精確點作操做。函數

分析

PS:防抖和節流的做用都是防止函數屢次調用。區別在於,假設一個用戶一直觸發這個函數,且每次觸發函數的間隔小於wait,防抖的狀況下只會調用一次, 而節流的 狀況會每隔必定時間(參數wait)調用函數。工具

防抖動和節流本質是不同的。防抖動是將屢次執行變爲最後一次執行,節流是將屢次執行變成每隔一段時間執行。post

袖珍版的防抖理解一下防抖的實現:

// func是用戶傳入須要防抖的函數
// wait是等待時間
const debounce = (func, wait = 50) => {
  // 緩存一個定時器id
  let timer = 0
  // 這裏返回的函數是每次用戶實際調用的防抖函數
  // 若是已經設定過定時器了就清空上一次的定時器
  // 開始一個新的定時器,延遲執行用戶傳入的方法
  return function(...args) {
    if (timer) clearTimeout(timer)
    timer = setTimeout(() => {
      func.apply(this, args)
    }, wait)
  }
}

複製代碼

不難看出若是用戶調用該函數的間隔小於wait的狀況下,上一次的時間還未到就被清除了,因此並不會執行函數

工具封裝

/**
 * 防抖函數,返回函數連續調用時,空閒時間必須大於或等於 wait,func 纔會執行
 *
 * @param  {function} func        回調函數
 * @param  {number}   wait        表示時間窗口的間隔
 * @param  {boolean}  immediate   設置爲ture時,是否當即調用函數
 * @return {function}             返回客戶調用函數
 */
function debounce(func, wait = 50, immediate = true) {
  let timer, context, args
  // 延遲執行函數
  const later = () => setTimeout(() => {
    // 延遲函數執行完畢,清空緩存的定時器序號
    timer = null
    // 延遲執行的狀況下,函數會在延遲函數中執行
    // 使用到以前緩存的參數和上下文
    if (!immediate) {
      func.apply(context, args)
      context = args = null
    }
  }, wait)

  // 這裏返回的函數是每次實際調用的函數
  return function (...params) {
    // 若是沒有建立延遲執行函數(later),就建立一個
    if (!timer) {
      timer = later()
      // 若是是當即執行,調用函數
      // 不然緩存參數和調用上下文
      if (immediate) {
        func.apply(this, params)
      } else {
        context = this
        args = params
      }
      // 若是已有延遲執行函數(later),調用的時候清除原來的並從新設定一個
      // 這樣作延遲函數會從新計時
    } else {
      clearTimeout(timer)
      timer = later()
    }
  }
}
複製代碼

具體的解釋註釋中都已經標明瞭,這裏就不作贅述了,至於節流函數,你們能夠自行實現。


開源庫

我的主頁 | bin-ui | bin-admin

相關文章
相關標籤/搜索