故事背景
面试官:‘你知道防抖节流吗?你是怎么理解的?’
我:(ps:哈哈哈哈哈哈我知道,还实现了,估计会问怎么实现了吧😄)嗯知道,blablabla
面试官:‘监听滚动事件你是选择用防抖还是节流?’
面试官:‘监听输入框的输入用防抖还是节流?’
面试官:‘移动端长列表用户疯狂下拉,用防抖还是节流?’
....
我:(ps:。。。。)。。。。
什么是防抖什么是节流
节流
节流就是规定某个时间段内只会执行一次。执行的是第一次。
防抖
防抖简单的理解就是很短时间内频繁触发时,它会很有耐心的去等到你的最后一次,这样的隐患就是在这个300ms内你啥都没看到-X- 这样就会造成卡顿....
如何真正从使用者的角度去选择呢?
- 用户做这个动作的时候,目的是干什么?
- 操作过程中如果使用了防抖或者节流会不会出现什么卡顿? 我们来举个🌰
- 滚动监听 滚动触发频率特别高,连续时间内可以一直触发,如果使用防抖,那么会一直卡着到最后,这样会造成卡顿 如果是节流,在固定时间内执行,这样相对来说不会卡顿,起码保证在一段时间内是会执行的
- input输入框输入 输入的时候会触发,但是我们实际上需要的就是用户输入之后的字符串就够了,不需要某个时间段拿一次,我们只关注输入完成之后的效果。所以这里考虑用防抖
- 长列表下拉 当用户封装下拉刷新,如果使用防抖做优化,那么可能在那段时间内用户不管下拉多少次都没有反应,这个时候就需要使用节流的方式来做,保证列表数据正常加载
- 屏幕resize 屏幕大小的变化过程其实不是我们需要关心的,而是变化之后需要做些什么,所以这个也是推荐使用防抖来做,这样每次执行的是最后一次的回调
PS: 以上只是我个人理解,有问题欢迎👏各位大佬提出
接下来看看你会选择防抖还是节流了吗
- 监听滚动事件
- 监听输入框输入
- 长列表封装下拉
- 屏幕resize
- 鼠标mousemove
- 按钮点击
- 鼠标拖拽
其实我们还有加强版
防抖和节流综合版
在防抖的基础上加上上次触发时间间隔rest判断,如果剩余时间<=0说明要执行了,如果小于,rest之后再执行
function lastOne(fn, delay){
var timer = null
var last = new Date().getTime()
return function() {
var now = new Date().getTime()
var that = this
var rest = delay - (now - last)
var args = arguments
clearTimeout(timer)
if(rest > 0) {
timer = setTimeout(()=>{
fn.apply(that, args)
}, rest)
}else{
fn.apply(that, args)
last = now
}
}
}