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

当用户频繁的与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(`请不要重复提交`); 
  };
};
相关推荐
gqkmiss24 分钟前
Chrome 浏览器 131 版本开发者工具(DevTools)更新内容
前端·chrome·浏览器·chrome devtools
Summer不秃30 分钟前
Flutter之使用mqtt进行连接和信息传输的使用案例
前端·flutter
旭日猎鹰34 分钟前
Flutter踩坑记录(二)-- GestureDetector+Expanded点击无效果
前端·javascript·flutter
Viktor_Ye40 分钟前
高效集成易快报与金蝶应付单的方案
java·前端·数据库
hummhumm43 分钟前
第 25 章 - Golang 项目结构
java·开发语言·前端·后端·python·elasticsearch·golang
乐闻x1 小时前
Vue.js 性能优化指南:掌握 keep-alive 的使用技巧
前端·vue.js·性能优化
一条晒干的咸魚1 小时前
【Web前端】创建我的第一个 Web 表单
服务器·前端·javascript·json·对象·表单
花海少爷1 小时前
第十章 JavaScript的应用课后习题
开发语言·javascript·ecmascript
Amd7941 小时前
Nuxt.js 应用中的 webpack:compiled 事件钩子
前端·webpack·开发·编译·nuxt.js·事件·钩子
生椰拿铁You2 小时前
09 —— Webpack搭建开发环境
前端·webpack·node.js