前端弄清函数节流、函数防抖、接口防重,再也不怕给页面或服务器造成负担了!

当用户频繁的与UI界面操作交互时,例如:窗口调整(触发resize),页面滚动(触发scroll),按钮点击(触发mousedown),实时搜索(触发keyup)等,可能导致界面卡顿、浏览器奔溃、页面空白等情况。

而解决这一问题的,正是函数节流与函数防抖。

函数节流

定义:

不管事件触发有多频繁,只会让一个函数在某个时间窗口内执行一次,若在时间窗口内再次触发,则重新计算时间。

应用场景:

常用于鼠标连续多次点击(click),鼠标连续移动(mousemove),窗口尺寸连续改动(resize),鼠标滚轮连续滚动(scroll)等。

原生代码实现:

js 复制代码
/* 
 * @description 封装节流函数 
 * @param { method, duration} [method是事件处理函数,duration是延迟时间]  
 * @return 匿名函数 
 * 原理: 通过判断是否达到一定的时间来触发函数
*/ 
export default function throttle(method, duration) { 
  let timer = null; 
  let prevTime = new Date(); // 之前的时间 
  return function() { 
    const that = this;
    const currentTime = new Date(); // 当前的时间 
    const resTime = currentTime - prevTime; // 时间戳
    // 当前距离上次执行时间小于设置的时间间隔 
    if (resTime < duration) { 
      // 清除上次的定时器,取消上次调用的队列任务,重新设置定时器。这样就可以保证500毫秒秒内函数只会被触发一次,达到了函数节流的目的 
      if(timer) {
        clearTimeout(timer);
      }; 
      timer = setTimeout(function() { 
        prevTime = currentTime; 
        method.apply(that, arguments); 
      }, duration);
    } else { 
       // 当前距离上次执行的时间大于等于设置的时间时,直接执行函数 
       // 记录执行方法的时间 
       prevTime = currentTime; 
       method.apply(that, arguments); 
    };
  };
};

第三方库实现

js 复制代码
import throttle from 'lodash.throttle'; // 引入lodash.throttle库

throttle(handleThrottle, 500); // 将触发事件处理函数作为第一个参数传入,第二个参数为间隔的时间,这里是500毫秒

函数防抖

定义:

当函数被触发后,只有在上一次函数执行一段时间后,才会再次触发函数

应用场景:

常应用于输入框搜索联想查询,只有在用户停止键盘输入时,才发送Ajax请求。

元素代码实现:

js 复制代码
/*
 * @description 函数防抖 
 * @param { method, duration} [method是事件处理函数,duration是延迟时间] 
 * @return 匿名函数 
 * 原理:它是维护一个计时器,规定在duration时间后触发事件处理函数,这样一来,只有最后一次操作事件处理函数才被真正的触发 
 */ 
export default function debounce(method, duration) { 
  let timer = null; 
  return function(){ 
    const that = this;
    // 在本次调用之间的一个间隔时间内若有方法在执行,则终止该方法的执行 
    if(timer) { 
      clearTimeout(timer); 
    };
    // 开始执行本次调用 
    timer = setTimeout(function(){ 
      method.apply(that, arguments); 
    }, duration) 
 } 
}

第三方库实现

js 复制代码
import debounce from 'lodash.debounce'; // 引入lodash.debounce库

debounce(handleDebounce, 500);; // 将触发事件处理函数作为第一个参数传入,第二个参数为间隔的时间,这里是500毫秒

节流与防抖小结

共同点

  • 都是解决频繁操作触发事件处理函数,引起页面卡顿,不流畅等性能问题
  • 都是通过设置延时器逻辑来提升性能,减少事件处理函数触发。

不同点

函数节流,间隔时间内执行事件处理函数,而函数防抖,一定时间间隔内只执行最后一次操作。

接口防重

除了节流和防抖,还有一种更为严格的防止重复提交,即前端在向后端进行数据提交的时候,必须要等到第一次提交的接口返回结果后,才能进行下一步操作,而不是像节流和防抖那样,规定一定时间。

一般来说,第三方UI组件库中的button按钮中都自带loading效果,我们只要控制loading开启关闭的时间即可达到此需求。

但是,有些时候,UI设计的按钮样式不适合放loading的时候,我们应该如何处理呢?

用flag标志 + toast提示, 伪代码如下:

js 复制代码
let sumitFlag = false;
const submit = () => { 
  if(!sumitFlag) {
    sumitFlag = true;
    //业务逻辑
  } else {
    ElMessage.warning(`请不要重复提交`); 
  };
};
相关推荐
程序员爱技术1 小时前
Vue 2 + JavaScript + vue-count-to 集成案例
前端·javascript·vue.js
并不会2 小时前
常见 CSS 选择器用法
前端·css·学习·html·前端开发·css选择器
悦涵仙子2 小时前
CSS中的变量应用——:root,Sass变量,JavaScript中使用Sass变量
javascript·css·sass
衣乌安、2 小时前
【CSS】居中样式
前端·css·css3
兔老大的胡萝卜2 小时前
ppk谈JavaScript,悟透JavaScript,精通CSS高级Web,JavaScript DOM编程艺术,高性能JavaScript pdf
前端·javascript
低代码布道师2 小时前
CSS的三个重点
前端·css
耶啵奶膘4 小时前
uniapp-是否删除
linux·前端·uni-app
王哈哈^_^5 小时前
【数据集】【YOLO】【目标检测】交通事故识别数据集 8939 张,YOLO道路事故目标检测实战训练教程!
前端·人工智能·深度学习·yolo·目标检测·计算机视觉·pyqt
cs_dn_Jie6 小时前
钉钉 H5 微应用 手机端调试
前端·javascript·vue.js·vue·钉钉
开心工作室_kaic6 小时前
ssm068海鲜自助餐厅系统+vue(论文+源码)_kaic
前端·javascript·vue.js