关于throttle(节流阀)和debounce(过滤器)的实现原理

原创 yehaikuo111 随笔 js复习 239阅读 2017-06-09 13:57:30 举报

先来说一下什么是节流阀和过滤器,相信学过电子的同学对过滤器一定不陌生,当初学51单片机的时候,处理按键一定会用到过滤器,因为如果不经过处理,按一次按键的时候按键其实是会抖动的,这就会让机器认为你按了很多次按键。解决方法也很简单,只要在第一次检测到按键的时候加一个几毫秒的延迟,再检测,如果检测到了按键依旧处于按下的状态,才认为是一次有效的按键动作。那这跟前端有什么关系呢?请看以下情况(将鼠标放在红色div上滑动,查看触发频率):
html 代码

相信大家都用过onmousemove和onresize事件吧,只要你鼠标一直移动或者窗口大小不停变化的时候,其实事件是一直在触发的,这非常消耗性能,对于频率要求没那么高的响应来说,这真的很浪费。其实,我们只是需要确认他是否进行了鼠标移动或者窗口调整,然后再进行响应就可以了。这就要用到定时器了,大家可以思考一下如何用定时器做到在事件一直触发的情况下,只响应一次呢?请看下面的demo:
html 代码

原理其实很简单就是触发事件的时候只开一个定时器,只要做过一些相关定时器项目的同学一定知道,如果我们只想开一个定时器的话,具体的做法就是把定时器先关后开。这样每次我们触发事件,就开启定时器,再触发事件就关掉定时器,再开启。一直到这个事件触发结束一段时间的时候,就让响应发生。这对于一些网页的优化很有帮助,比如通过改变窗口大小,从而改变元素的排列,其实我们不需要随着窗口的改变,实时的改变元素排列,只需要知道窗口最后的状态即可,还有一些类似于表单提交事件,用户一直不停的点击提交,也可以用到这个方法来过滤无效操作。

下面来介绍一下节流阀,节流阀其实和过滤器很相似,但是响应频率要高一些,有时候我们可能对响应的发生频率有要求(请注意响应频率和事件触发频率的区别,时间触发频率我们我们是不可控的),比如拖拽。当然响应频率我们也是可以控制的,就是通过定时器的时间来控制。那么节流阀具体到之前的demo中应该是什么样的呢?比如,我鼠标一直在div上滑动的时候,我希望它起码给我500ms要响应一次(也就是数字要+1),这其实跟防抖器原理很相似,但是我们要通过判断状态来实现这个功能:

html 代码

第一次看到这种实现方法的时候,不禁赞叹设计的巧妙,需要学习的还有很多,大家如果对本文章感兴趣,可以看看underscore里面是如何对这两只方法进行完善的实现的。
评论 ( 0 )
最新评论
暂无评论

赶紧努力消灭 0 回复