Open zhongxia245 opened 5 years ago
简单的防抖,节流函数的实现,面试中,可能让你手写这两个方法,因此需要自己理解下原理,然后敲一两遍,加深记忆。(看了都懂,听了都会,上手全废)
/**
* 【简单版】防抖函数
* 使用 setTimeout 和 clearTimeout 来实现
* @param {function} fn 需要防抖的函数
* @param {number} wait 防抖的等待时间
*/
const debounce = (fn, wait = 100) => {
// 通过闭包记录浏览器标识
let timer = null
// 通过防抖处理,会返回一个新的函数
return function(...args) {
// 已经设置过定时器,则清空上一次的定时器,重新开始计时
if (timer) clearTimeout(timer)
// 设定一个新的定时器,定时器结束后开始执行传入的函数
timer = setTimeout(() => {
fn.apply(this, args)
}, wait)
}
}
/**
* 增加立即执行的防抖函数
* @param {function} fn 需要防抖的函数
* @param {number} wait 防抖的等待时间
* @param {bool} immediate 是否立即执行
*/
const debounce1 = (fn, wait = 100, immediate = false) => {
let timer = null
return function(...args) {
if (timer) clearTimeout(timer)
// 放开始立即执行一次, 定时器未空的时候,就是第一次。
if (immediate && !timer) {
fn.apply(this, args)
}
timer = setTimeout(() => {
fn.apply(this, args)
}, wait)
}
}
/**
* 【简单版】函数节流
* @param {function} fn 需要防抖的函数
* @param {number} wait 节流的等待时间
*/
const throttle = (fn, wait = 100) => {
// 通过闭包记录开始时间
let start = 0
return function(...args) {
let now = Date.now()
// 当前时间减去开始时间,大于间隔的时间,则执行函数
if (now - start > wait) {
start = now
fn.apply(this, args)
}
}
}
/**
* 函数节流
* 触发时间如果小于间隔时间,则使用防抖来执行函数
* @param {function} fn 需要防抖的函数
* @param {number} wait 节流的等待时间
*/
const throttle1 = (fn, wait = 100) => {
// 通过闭包记录开始时间
let start = 0
let timer = null
return function(...args) {
let now = Date.now()
// 当前时间减去开始时间,大于间隔的时间,则执行函数
if (now - start > wait) {
start = now
fn.apply(this, args)
} else {
// 解决用户最后一次操作距离上一次触发时间的时长打不到 wait 时长,为用户的最后一次操作进行兜底
if (timer) clearTimeout(timer)
timer = setTimeout(() => {
start = now
fn.apply(this, args)
}, wait)
}
}
}
一、What?
防抖函数(debounce) :某个函数在某段时间内,无论触发了多少次回调,都只执行最后一次。
函数节流(throttle) :某个函数在一定时间间隔内(例如 3 秒)只执行一次,在这 3 秒内 无视后来产生的函数调用请求,也不会延长时间间隔。
二、When?
防抖函数:
节流函数:
三、How?
这两个函数,是闭包的应用,它会返回一个新的函数。
因此,使用方式如下
四、常见问题
1. React 中,如果类似这样使用防抖函数,会获取input 的值,因为 e.target 为空
终、参考文章
1、 《【进阶 6-4 期】深入浅出防抖函数 debounce》 2、《在 react 组件中使用 debounce 函数》