限制函數調用頻率,快速點擊時,限制其一定時間內只觸發一次事件,如ajax提交,連續點擊提交按鈕,會發送多次請求,使用去抖可以避免多次重複請求
簡介
debounce(fun, delay, immediate)
當調用函數n秒後,纔會執行該動作,若在這n秒內又調用該函數則將取消前一次並重新計算執行時間
原理
-
參數
func - 函數
delay - 延時
immediate - 立即執行 -
變量
lasttime - 上一次觸發時間
timer - 定時器
context -上下文
args - 參數 -
定時執行函數 - 判斷是否執行動作
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.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
}
}
}