Javascript - 防抖和节流

217 阅读2分钟

在阅读了掘金的一篇关于防抖和节流的分享之后,对防抖和节流的含义有了更好的理解。然后希望通过研究 loadash 中防抖和节流的源码,进一步加深对防抖和节流的认识,并总结出这种技术常用的使用场景。

在 David Corbacho 的论文中,也有段描述,很好的描述了防抖和节流的用途:这两种技术就是要控制在某段时间里某个方法的执行次数。

Debounce and throttle are two similar (but different!) techniques to control how many times we allow a function to be executed over time.

论文中还提到了在 2011 年被讨论的一个经典案例,在案例中我们看到无限制的调用一个昂贵的方法反而会影响用户的体验。

In 2011, an issue popped up on the Twitter website: when you were scrolling down your Twitter feed, it became slow and unresponsive. John Resig published a blog post about the problem where it was explained how bad of an idea it is to directly attach expensive functions to the scroll event.

此时,限制其实就变得很有必要了,而且作用也是积极的。

哎,本来希望可以在掘金中直接插入 codePen 的内容,让信息看起来更加直观呢,结果还是没成功。

防抖

防止某个方法被频繁调用,在一段时间内,只在最后一个触发调用一次。

<!DOCTYPE HTML>
<html>
    <head>
        <title>地铁闸机</title>
        <style type="text/css">
            #door {
                height: 100px;
                width: 100px;
                background-color: aquamarine;
                text-align: center;
            }
        </style>
    </head>
    <body>
        <div id="door" onclick="openDoor()">接触刷卡</div>
        <div>
            <p>通过人数:<span id="counter">0</span></p>
            <p id="status">闸机关闭</p>
            <p id="info"></p>
        </div>
        <script type="text/javascript">
            var passby = 0;
            var closed = true;
            var closedTimer =null;
            function openDoor () {
                closed = false;
                if (!closed) {
                    console.log('openDoor........')
                    passby += 1;
                    document.getElementById('counter').innerHTML = passby
                    document.getElementById('status').innerHTML = '闸机开启'
                } else {
                    document.getElementById('status').innerHTML = '请重新刷卡!'
                }
                // 1 秒中后门自动关闭
                setTimeout(closeDoor, 1000)
                // 增加防抖
                // initClosedProcess ()
            }
            function initClosedProcess () {
                if (closedTimer) {
                    clearTimeout(closedTimer)
                }
                closedTimer = setTimeout(closeDoor, 1000)
            }
            // 关门刚发被调用很多次
            function closeDoor () {
                console.log('closeDoor.........')
                closed = true;
                document.getElementById('info').innerHTML += '闸机关闭启动...'
                document.getElementById('status').innerHTML = '闸机关闭'
            }
        </script>
    </body>
</html>