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

当用户频繁的与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(`请不要重复提交`); 
  };
};
相关推荐
鼎道开发者联盟22 分钟前
鼎享会 | OpenClaw Control UI 前端架构全解析:自研 UI 对接 Server 实操指南
前端·ui·架构·openclaw·control ui
尘世中一位迷途小书童24 分钟前
一套完整的给予ceium封装的组件库,可满足企业级开发
前端
Z_Wonderful25 分钟前
微前端:Webpack 配置 vs Vite 配置 超清晰对比
前端·webpack·node.js
thankseveryday27 分钟前
Three.js 把 Blender 绘制的曲线(Bezier / 曲线) 导入 Three.js 并作为运动路径 / 动画路径使用
开发语言·javascript·blender
码云数智-园园30 分钟前
HTTPS是如何工作的?从HTTP到HTTPS的加密演进
前端
隔窗听雨眠38 分钟前
HTML头部元信息避坑指南
前端·html
Gauss松鼠会1 小时前
【openGauss】openGauss 磁盘引擎之 ustore
java·服务器·开发语言·前端·数据库·经验分享·gaussdb
LIO1 小时前
前端响应式页面开发全攻略:核心技术 + 实现效果 + 实战指南
前端·响应式设计
得物技术1 小时前
AI驱动:从运营行为到自动化用例的智能化实践|得物技术
前端·ai编程·全栈
前端那点事1 小时前
Vue并发控制|几十个请求高效管控(实战方案+可运行代码)
前端·vue.js