debounce函數去抖實現

限制函數調用頻率,快速點擊時,限制其一定時間內只觸發一次事件,如ajax提交,連續點擊提交按鈕,會發送多次請求,使用去抖可以避免多次重複請求

簡介

debounce(fun, delay, immediate)
當調用函數n秒後,纔會執行該動作,若在這n秒內又調用該函數則將取消前一次並重新計算執行時間

原理

  1. 參數
    func - 函數
    delay - 延時
    immediate - 立即執行

  2. 變量
    lasttime - 上一次觸發時間
    timer - 定時器
    context -上下文
    args - 參數

  3. 定時執行函數 - 判斷是否執行動作
    3.1 獲取當前距上次觸發時間間隔l。
    3.2 判斷間隔是否小於延時並大於0(小於0代表lasttime在now之後) 轉至3.3;轉至3.4。
    3.3 清除當前定時器,重新設置定時器,時間爲剩餘時間delay-l。
    3.4 是否立即執行時(immediate)轉至3.6;轉至3.5。
    3.5 執行fun;上下文、參數初始化null。
    3.4 此次調用結束,清空定時器 timer置null。

  4. 主流程
    4.1 賦值、
    4.2 定時器不存在則設定定時器、
    4.3 判斷是否立即執行且爲第一次觸發timer爲null 執行3.5

實現

/**
 * 去抖
 * @param {*} fun 調用函數
 * @param {*} delay 延時
 * @param {*} immediate 立即執行
 */
const debounce = function (fun, delay, immediate) {
  var timer, lasttime, context, arg
  var later = function () {
    var now = new Date().getTime(),
      l = now - lasttime //獲取間隔
    if (l < delay && l >= 0) {
      clearTimeout(timer)
      timer = setTimeout(later, delay - l) //重新設置定時器,delay-l時間後執行
    } else {
      if (!immediate) { // 非立即執行
        fun.apply(context, arg) //執行調用函數
        if (timer) context = arg = null // 執行完成初始化上下文和arg
      }
      clearTimeout(timer)
      timer = null
    }
  }
  return function () {
    context = this // 賦值func上下文
    arg = arguments // 賦值func參數
    lasttime = new Date().getTime() // 設置最新時間
    var callNow = immediate && !timer // 判斷是否立即執行且爲第一次觸發
    if (!timer) timer=setTimeout(later, delay) // 定時器不存在設置定時器
    if (callNow) { // 立即執行一次
      fun.apply(context, arg)
      context = arg = null
    }
  }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章