代码优化-抖动节流
最近在写项目的时候,发现一个搜索框居然没有使用抖动,作为一名优秀😜的前端开发工程师,我怎么能容忍这种事情发生,于是就自己写了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
里面都要实现: