JavaScript函数的节流与防抖
函数的 节流和防抖 可以有效的防止,函数频繁无意义的执行。至于选用节流还是防抖,得看具体的应用场景。
/*----------------------------------防抖函数---------------------------------*/
/**
* @description 防抖函数(debounce)(延迟执行版)--短时间内多次触发同一事件,只执行最后一次,中间的不执行
* @param func 要进行防抖的函数
* @param delay 延迟执行毫秒数
* @param context 上下文环境
* @return 返回防抖处理后的函数
*/
function debounce(func, delay, context) {
let timer
return function(...args) {
if (timer) clearTimeout(timer)
timer = setTimeout(() => {
func.apply(context, args)
}, delay)
}
}
/**
* @description 防抖函数(debounce)(立即执行版)--短时间内多次触发同一事件,只执行最开始的一次,中间的不执行
* @param func 要进行防抖的函数
* @param delay 延迟执行毫秒数
* @param context 上下文环境
* @return 返回防抖处理后的函数
*/
function debounce(func, delay, context) {
let timer
return function(...args) {
if (timer) clearTimeout(timer)
let callNow = !timer
timer = setTimeout(() => {
timer = null
}, delay)
if (callNow) func.apply(context, args)
}
}
/**
* @description 防抖函数(debounce)(组合版)--短时间内多次触发同一事件,只执行最后一次,
* 或者只执行最开始的一次,中间的不执行
* @param func 要进行防抖的函数
* @param delay 延迟执行毫秒数
* @param immediate 是否立即执行
* @param context 上下文环境
* @return 返回防抖处理后的函数
*/
function debounce(func, delay, immediate, context) {
let timer
return function(...args) {
if (timer) clearTimeout(timer)
if (immediate) {
let callNow = !timer
timer = setTimeout(() => {
timer = null
}, delay)
if (callNow) func.apply(context, args)
} else {
timer = setTimeout(() => {
func.apply(context, args)
}, delay)
}
}
}
/*----------------------------------节流函数---------------------------------*/
/**
* @description 节流函数(throttle) 时间戳版(立即执行的)--指连续触发事件但是在 n 秒中只执行一次函数。
* 即 2n 秒内执行 2 次... 。节流如字面意思,会稀释函数的执行频率
* @param func 要进行节流的函数
* @param delay 延迟执行毫秒数
* @param context 上下文环境
* @return 返回节流处理后的函数
*/
function throttle(func, delay, context) {
let previous = 0
return function(...args) {
let now = Date.now()
if (now - previous > delay) {
func.apply(context, args)
previous = now
}
}
}
/**
* @description 节流函数(throttle) 定时器版(延迟后执行的)--指连续触发事件但是在 n 秒中只执行一次函数。
* 即 2n 秒内执行 2 次... 。节流如字面意思,会稀释函数的执行频率
* @param func 要进行节流的函数
* @param delay 延迟执行毫秒数
* @param context 上下文环境
* @return 返回节流处理后的函数
*/
function throttle(func, delay, context) {
let timeout
return function(...args) {
if (!timeout) {
timeout = setTimeout(() => {
timeout = null
func.apply(context, args)
}, delay)
}
}
}
/**
* @description 节流函数(throttle)(组合版)--指连续触发事件但是在 n 秒中只执行一次函数。
* 即 2n 秒内执行 2 次... 。节流如字面意思,会稀释函数的执行频率
* @param func 要进行节流的函数
* @param delay 延迟执行毫秒数
* @param type 1 时间戳版(立即执行的) 2 定时器版(延迟后执行的)
* @param context 上下文环境
* @return 返回节流处理后的函数
*/
function throttle(func, delay, type, context) {
let previous = 0
let timeout
return function(...args) {
if (type === 1) {
let now = Date.now()
if (now - previous > delay) {
func.apply(context, args)
previous = now
}
} else if (type === 2) {
if (!timeout) {
timeout = setTimeout(() => {
timeout = null
func.apply(context, args)
}, delay)
}
}
}
}