小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。
手撕面试常客之函数的防抖和节流
函数防抖
(debounce)在用户频繁触发某个行为的时候,我们只识别一次即可。
/*
debounce:函数防抖
@params
func:自己最终要执行的任务
wait:多久操作一次算是频繁触发[默认值:500ms]
immediate:控制触发的边界[默认值:false结束边界 true开始边界](以点击按钮为例:[开始边界:第一次点击触发 结束边界:等到最后一次触发])
@return
operate处理函数,处理函数会在频繁触发的时候,频繁执行,函数内部,控制我们想要操作的func只执行一次
*/
const debounce = function debounce(func, wait, immediate) {
if (typeof func !== 'function') throw new TypeError(`${func} is not a function`)
if(typeof wait === 'boolean') immediate = wait
if(typeof wait !== ' number') wait = 500
if(typeof immediate !== 'boolean') immediate = false
const clearTimer = function clearTimer(timer){
if (timer) {
clearTimeout(timer)
}
return null
}
let timer = null
return function operate(...params){
let now = !timer && immediate
timer = clearTimer(timer)
timer = setTimeout(() => {
timer = clearTimer(timer)
//结束边界触发
if(!immediate) func.call(this, ...params)
}, wait)
//开始边界触发
if (now) func.call(this, ...params)
}
}
函数节流
(throttle)在频繁操作的时候,我们能降低触发的频率 (执行的频率自己来设定)。
/**
*
* @param {*} func 需要处理的函数
* @param {*} wait 多久触发一次
*
* @return
operate处理函数,处理函数会在频繁触发的时候,频繁执行,函数内部,控制我们想要操作的func按照规定的频率执行
*/
const throttle = function throttle(func, wait){
if(typeof func !== 'function') throw new TypeError(`${func} is not a function`)
if(typeof wait !== 'number') wait = 500
const clearTimer = function clearTimer(tiemr){
if (timer) {
clearTimeout(timer)
}
return null
}
let timer = null,
previous = 0
return function operate(...params){
let now = +new Date(),
remaining = wait - (now - previous)
if (remaining <= 0) {
// 两次间隔时间超过500ms了,让其方法立即执行
func.call(this, ...params)
previous = +new Date()
}else if (!timer) {
// 没设置过定时器等待,则我们设置一个去等待
timer = setTimeout(() => {
timer = clearTimer(timer)
func.call(this, ...params)
previous = +new Date()
}, remaining)
}
}
}