15 # 手写 throttle 节流方法

什么是节流

节流是限制事件触发的频率,当持续触发事件时,在一定时间内只执行一次事件,这个效果跟英雄联盟里的闪现技能释放差不多。

函数防抖关注一定时间连续触发的事件只在最后执行一次,而函数节流侧重于一段时间内只执行一次。

间隔一段时间执行一次回调的场景有:

  • 滚动加载,加载更多或滚到底部监听
  • 谷歌搜索框,搜索联想功能
  • 高频点击提交,表单重复提交
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>节流</title>
    <script src="https://cdn.bootcdn.net/ajax/libs/underscore.js/1.13.6/underscore-min.js"></script>
</head>

<body>
    <div>
        普通输入框:
        <input class="input1" />
    </div>
    <div>
        节流输入框:
        <input class="input2" />
    </div>
    <script>
        // 普通
        const inputEl1 = document.querySelector(".input1");
        let counter1 = 1;
        inputEl1.oninput = function () {
      
      
            console.log(`发送网络请求${ 
        counter1++}`, this.value);
        };
        // 节流处理过的
        const inputEl2 = document.querySelector(".input2");
        let counter2 = 1;
        inputEl2.oninput = _.throttle(function () {
      
      
            console.log(`节流处理:发送网络请求${ 
        counter2++}`, this.value);
        }, 1000);
    </script>
</body>

</html>

在这里插入图片描述

手写 throttle

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>手写节流</title>
    <script>
        // 时间戳实现节流
        function kaimoThrottle(fn, delay) {
      
      
            let startTime = 0;
            let _throttle = function (...args) {
      
      
                let now = new Date().getTime();
                let waitTime = delay - (now - startTime);
                if (waitTime <= 0) {
      
      
                    fn.apply(this, args);
                    startTime = now;
                }
            }
            return _throttle;
        }
        // setTimeout 实现节流
        function kaimoThrottle2(fn, delay) {
      
      
            let timer = null;
            let _throttle = function (...args) {
      
      
                // 如果 timer 不为 null,说明上一个定时器还未执行,则直接返回
                if (timer) {
      
      
                    return;
                }
                // 开启新的一个定时器
                timer = setTimeout(() => {
      
      
                    // this 和参数绑定
                    fn.apply(this, args);
                    // 函数执行完之后,将timer置为null
                    timer = null;
                }, delay);
            };
            return _throttle;
        }
    </script>
</head>

<body>
    <div>
        节流输入框:
        <input class="input" />
    </div>
    <script>
        const inputEl = document.querySelector(".input");
        let counter = 1;
        inputEl.oninput = kaimoThrottle2(function (e) {
      
      
            console.log(`手写节流:发送网络请求${ 
        counter++}`, this, this.value);
            console.log(e);
        }, 1000);
    </script>
</body>

</html>

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/kaimo313/article/details/134351222