代码优化-抖动节流
最近在写项目的时候,发现一个搜索框居然没有使用抖动,作为一名优秀😜的前端开发工程师,我怎么能容忍这种事情发生,于是就自己写了debounce和throttle
抖动(debounce)
使用场景:当用户使用搜索框的时候,如果搜索框每发生一次改变就发一次请求的话(这就是我在写的项目的现状😥)就会找出巨大的浪费,用户可能只是想停下来想一下搜索关键字,这个时候抖动就有了很大的作用,它的作用是当用户停止操作(输入)的时候,并不会立即发请求,而是等经过一段时间后再发请求
体验一下酸爽

分析一下,debounce需要实现的功能:
- 指定时间后在执行需要的操作
- 每次操作(比如输入)都需要重新开始计时
function debounce (fn, delayTime) {
let timeOut
return function () {
let args = arguments
clearTimeout(timeOut)
timeOut = setTimeout(function () {
fn.apply(this, args)
}, delayTime)
}
}看一下实际使用效果

实战才是硬道理,在项目中使用试试

没有以前那么夸张了,当然这也是个半成品,下面的搜索结果框没有出现,哈哈哈。在实现的过程中也遇到了一下问题,在此记录下:
- 项目中使用了 dva中的dispatch去发送请求(dva类似于reducer,也是用于状态管理),我开始是这样写的
debounceSearch = debounce(dispatch({
type: 'car/comlist',
payload: {
level1Type: '半导体',
},
}), 1500)直接将dispatch传了进去,然后后面发请求就一直报fn is undefined ,稍微想了一下dispatch不是一个function,然后直接用一个函数去包裹它,在加上参数的传入😁
debounceSearch = debounce((args) => dispatch({
type: 'car/comlist',
payload: {
level1Type: '半导体',
...args
},
}), 1500)- 项目用的前端框架是React,但没有使用Class,全部用React Hook(函数是一等公民😂),我对React Hook不是很熟悉,
debounceSearch需要在DOM加载完之后就要生成,对于React的生命周期是componentDidMount,其实在componentWillMount也是可以的,但这个生命周期要被废弃了,不推荐使用。在React Hook里面使用useEffect可以代替componentDidMount和componentDidUpdate
debounceSearch = debounce((args) => dispatch({
type: 'car/comlist',
payload: {
level1Type: '半导体',
...args
},
}), 1500)Bingo,debounce已经结束了
throttle(节流)
使用场景:在秒杀活动中,快到时间的时候就会一直点点点,希望可以抢到心怡的东西,如果每点一次就发一次请求的话,服务器肯定受不了,throttle这时候就展现它的用处了,它会按照一定的时间间隔发请求,这样就可以减轻服务器压力,另外的一个效果是你的点击不是每一次都有用
分析一下throttle需要实现的功能:
- 按照一定的时间间隔去处理特定动作
上代码
function throttle (fn, delayTime) {
let last, timeOut
return function () {
let args = arguments
let now = new Date()
if (last && now - last < delayTime) {
clearTimeout(timeOut)
timeOut = setTimeout(function () {
last = now
fn.apply(this, args)
}, delayTime)
} else {
last = now
fn.apply(this, args)
}
}
}实现效果:

虽然我一直点点点,但它还是按照规定的时间间隔处理
所有的代码已经放到我的github 上去了
如果你不想写的话
Lodash里面都要实现: