限制函数调用频率,快速点击时,限制其一定时间内只触发一次事件,如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
}
}
}