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

前端开发属于哪个方面
前端开发还是后端开发哪个好
前端开发哪个城市

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

<!DOCTYPE html>
    <head>
        <meta charset=”UTF-8″ />
        <title></title>
        <script src=”http://cdn.bootcss.com/jquery/1.10.1/jquery.min.js”></script>
        <style>
            .box {
                width: 200px;
                height: 200px;
                background: red;
                font-size: 50px;
                color: #fff;
                text-align: center;
                line-height: 200px;
            }
        </style>
    </head>
    <body>
        <div class=”box”></div>
        <script>
            var n = 0
            $(‘.box’).mousemove(function() {
                $(this).html(n++)
            })
        </script>
    </body>
</html>

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

<!DOCTYPE html>
<html>
    <head>
        <meta charset=”UTF-8″ />
        <title></title>
        <script src=”http://cdn.bootcss.com/jquery/1.10.1/jquery.min.js”></script>
        <style>
            .box {
                width: 200px;
                height: 200px;
                background: red;
                font-size: 50px;
                color: #fff;
                text-align: center;
                line-height: 200px;
            }
        </style>
    </head>
    <body>
        <div class=”box”></div>
        <script>
            /*var n=0;
$(‘.box’).mousemove(function(){
$(this).html(n++);
            });*/
            var n = 0
            var timer = null
            $(‘.box’).mousemove(function() {
                clearTimeout(timer)
                timer = setTimeout(function() {
                    $(‘.box’).html(++n)
                }, 200)
            })
        </script>
    </body>
</html>

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

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

html 代码

<!DOCTYPE html>
<html>
    <head>
        <meta charset=”UTF-8″ />
        <title></title>
        <script src=”http://cdn.bootcss.com/jquery/1.10.1/jquery.min.js”></script>
        <style>
            .box {
                width: 200px;
                height: 200px;
                background: red;
                font-size: 50px;
                color: #fff;
                text-align: center;
                line-height: 200px;
            }
        </style>
    </head>
    <body>
        <div class=”box”></div>
        <script>
            /*var n=0;
$(‘.box’).mousemove(function(){
$(this).html(n++);
            });*/
            var n = 0
            var timer = null
            var flag = true
            $(‘.box’).mousemove(function() {
                if (flag) {
                    $(‘.box’).html(++n)
                    flag = false
                    timer = setTimeout(function() {
                        flag = true
                    }, 500)
                }
            })
        </script>
    </body>
</html>
第一次看到这种实现方法的时候,不禁赞叹设计的巧妙,需要学习的还有很多,大家如果对本文章感兴趣,可以看看underscore里面是如何对这两只方法进行完善的实现的。
前端和开发哪个好学
前端开发和产品经理哪个好
前端开发与大数据哪个更受欢迎
 
» 本文来自:前端开发者 » 《前端关于throttle(节流阀)和debounce(过滤器)的实现原理》
» 本文链接地址:https://www.rokub.com/8195.html
» 您也可以订阅本站:https://www.rokub.com
赞(1)
64K

评论 抢沙发

评论前必须登录!