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

当用户频繁的与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(`请不要重复提交`); 
  };
};
相关推荐
Mintopia3 分钟前
Web 安全与反编译源码下的权限设计:构建前后端一体的信任防线
前端·安全·编译原理
林深现海24 分钟前
Jetson Orin nano/nx刷机后无法打开chrome/firefox浏览器
前端·chrome·firefox
黄诂多38 分钟前
APP原生与H5互调Bridge技术原理及基础使用
前端
前端市界41 分钟前
用 React 手搓一个 3D 翻页书籍组件,呼吸海浪式翻页,交互体验带感!
前端·架构·github
文艺理科生42 分钟前
Nginx 路径映射深度解析:从本地开发到生产交付的底层哲学
前端·后端·架构
千寻girling43 分钟前
主管:”人家 Node 框架都用 Nest.js 了 , 你怎么还在用 Express ?“
前端·后端·面试
C澒1 小时前
Vue 项目渐进式迁移 React:组件库接入与跨框架协同技术方案
前端·vue.js·react.js·架构·系统架构
xiaoxue..1 小时前
合并两个升序链表 与 合并k个升序链表
java·javascript·数据结构·链表·面试
清山博客1 小时前
OpenCV 人脸识别和比对工具
前端·webpack·node.js
要加油哦~1 小时前
AI | 实践教程 - ScreenCoder | 多agents前端代码生成
前端·javascript·人工智能