浅谈JS函数节流及应用场景

说完防抖,下面我们讲讲节流,规矩就不说了,先上代码:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>节流</title>
</head>
<body>

  <button id="throttle">点我节流!</button>

  <script>
    window.onload = function() {
      // 1、获取按钮,绑定点击事件
      var myThrottle = document.getElementById("throttle");
      myThrottle.addEventListener("click", throttle(sayThrottle));
    }

    // 2、节流函数体
    function throttle(fn) {
      // 4、通过闭包保存一个标记
      let canRun = true;
      return function() {
        // 5、在函数开头判断标志是否为 true,不为 true 则中断函数
        if(!canRun) {
          return;
        }
        // 6、将 canRun 设置为 false,防止执行之前再被执行
        canRun = false;
        // 7、定时器
        setTimeout( () => {
          fn.call(this, arguments);
          // 8、执行完事件(比如调用完接口)之后,重新将这个标志设置为 true
          canRun = true;
        }, 1000);
      };
    }

    // 3、需要节流的事件
    function sayThrottle() {
      console.log("节流成功!");
    }

  </script>
</body>
</html>

很好,看完代码的小伙伴应该大致清楚是怎么回事了,下面我们看 GIF 实现:

看完代码和 GIF 实现,我们可以明白,节流即是:

  • 节流指定时间间隔内只会执行一次任务。

那么,节流在工作中的应用?

  1. 懒加载要监听计算滚动条的位置,使用节流按一定时间的频率获取。
  2. 用户点击提交按钮,假设我们知道接口大致的返回时间的情况下,我们使用节流,只允许一定时间内点击一次。

这样,在某些特定的工作场景,我们就可以使用防抖与节流来减少不必要的损耗。

那么问题来了,假设面试官听到你这句话,是不是会接着问一句:“为什么说上面的场景不节制会造成过多损耗呢?”

OK,这就涉及到浏览器渲染页面的机制了……



案例2:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>demo</title>
</head>
<body>
    <input type="text" name="search">

    <script type="text/javascript">
        var searchInput = document.querySelector('input[name="search"]');
        /*绑定事件*/
        searchInput.addEventListener('keyup',throttle(getInputValue),false);
        /* 节流函数 */
        function throttle(fn){
            /*通过闭包保存一个标记*/
            let timer = true;
            return function(){
                /*在函数开头判断标志是否为 true,不为 true 则中断函数*/
                if(!timer){
                    return;
                }
                /*将 timer 设置为 false,防止执行之前再被执行*/
                timer = false;
                /* 定时器 */
                setTimeout(()=>{
                    fn.call(this,arguments)
                    /*执行完事件(比如调用完接口)之后,重新将这个标志设置为 true*/
                    timer = true;
                },1000)
            }
        }
        /* 调用获取输入值 */
        function getInputValue(){
            console.dir(this.value)
        }
    </script>
</body>
</html>

.

猜你喜欢

转载自www.cnblogs.com/jianxian/p/12077570.html