欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

防抖和节流

程序员文章站 2022-05-10 15:01:56
...

工作场景

  1. 用户在搜索的时候,如果每敲一个字就调用一次接口,接口调用频繁容易卡住
  2. 监听滚动,监听用户滚动的位置,如果每滚动一次就监听,操作频繁占内存
  3. 表单提交

防抖

在任务频繁触发的情况下,只有任务触发的间隔超过指定间隔的时候,任务才会执行。
例如:搜索框,输入之后会调用接口,获取联想词;为避免频繁调用接口,在代码中使用防抖,在用户输入完毕的一段时间后,才会调用接口

节流

指定的时间间隔只执行一次,
例如:点击提交按钮,我们知道接口大致的返回时间,使用节流,只允许规定的时间内点击一次,

实现防抖

// <button id="btn" >点击防抖</button>
	function debounce(fn,wait){
      var timerId = null;
      var immediate = true;
      return function(){
        clearTimeout(timerId);
        if (immediate) {
          fn.call(this,arguments);
          immediate = false
        }
        timerId = setTimeout(() => { immediate = true},wait)
      }
    }
    
	// 节流事件
    const func = debounce_2((e) => {
      console.log('防抖');
    }, 1000)

    const btn = document.getElementById('btn')
    btn.addEventListener('click', func)

实现节流

// <button id="throttle">点我节流!</button>
      var myThrottle = document.getElementById("throttle");
      myThrottle.addEventListener("click", throttle(this.sayThrottle));

      // 节流函数体——闭包标记符号版
      function throttle(fn, delay = 2000) {
        // 通过闭包保存执行标记和立即执行标记
        let canRun = true;
        var immediate = true;
        return function() {
          // 在函数开头判断标志是否为 true,不为 true 则中断函数
          if (!canRun) {
            return;
          }
          // 判断是否立即执行
          if (immediate) {
            fn.call(this, arguments);
            immediate = false;
          } else {
            // 将 canRun 设置为 false,防止执行之前再被执行
            canRun = false;
            // 定时器
            setTimeout(() => {
              fn.apply(this, arguments);
              // 执行完事件(比如调用完接口)之后,重新将这个标志设置为 true
              canRun = true;
              immediate = true;
            }, delay);
          }
        };
      }
      
	// 节流函数体——闭包标记+时间戳 来源:https://juejin.im/post/5c6bab91f265da2dd94c9f9e#heading-12
	function throttle2(fun, delay = 2000) {
        let timer = null;
        let previous = 0;
        return function(args) {
          let now = Date.now();
          let remaining = delay - (now - previous); // 操作间隔时间距离规定时间,还剩多少久
          let that = this;
          let _args = args;
          clearTimeout(timer); // 清除之前设置的定时器
          if (remaining <= 0) {
            fun.apply(that, _args);
            previous = Date.now();
          } else {
            timer = setTimeout(function() {
              fun.apply(that, _args);
            }, remaining); // 因为上面添加的clearTimeout.实际这个定时器只有最后一次才会执行
          }
        };
      }
      
	// 需要节流的事件
      function sayThrottle() {
        console.log("节流成功!");
      }

理解区别:防抖,完全禁止频繁触发;节流将频繁触发改为规定时间内触发

相关标签: 前端基础

上一篇: 前端学习一

下一篇: 前端基础学习