评论

函数的节流与防抖在答题小程序项目中的应用

无论是公司项目,还是个人项目,往往会遇到这样的一些造成回调开销加大的问题,比如重复提交、快速点击、高频事件等。为了规避这种情况,我们需要一些手段来控制事件被触发的频率。

通常,scroll 事件,resize 事件、鼠标事件(比如 mousemove、mouseover 等)、键盘事件(keyup、keydown 等)都存在被频繁触发的风险。频繁触发回调导致的大量计算会引发页面的抖动甚至卡顿。

无论是公司项目,还是个人项目,往往会遇到这样的一些造成回调开销加大的问题,比如重复提交、快速点击、高频事件等。

为了规避这种情况,我们需要一些手段来控制事件被触发的频率。然而,节流(throttle)与防抖(debounce)是我们在日常开发中常用的优质代码片段,能够给我们的项目带来性能的提升。

问题


小程序端以答题考试知识库项目为例,存在的问题:

1)重复提交

单位时间内,多次请求,造成的后台重复录入现象。

2)快速点击

单位时间内,快速点击查询或者答题,触发异步事件,造成数据与ui混乱的现象。

3)高频事件

单位时间内,触发的各类事件,且响应速度低于请求,造成的卡顿或其他混乱现象。


节能知识竞赛-提交答卷:



考研知识库-模糊查询:





人物评选投票-精准搜索:






解决方案

一般在项目中比较常见用的方式是事件或函数的节流(throttle)与防抖(debounce)。



节流(throttle)与防抖(debounce)的本质

这两个东西都以闭包的形式存在。

它们通过对事件对应的回调函数进行包裹、以自由变量的形式缓存时间信息,最后用 setTimeout 来控制事件的触发频率。



节流(throttle)

节流:每间隔某个时间去执行某函数。

节流(throttle) 的中心思想在于:在某段时间内,不管你触发了多少次回调,我都只认第一次,并在计时结束时给予响应。

function throttle(fn: Function, delay: number) {
  let timer: any = null;

  return function () {
    if (timer) return;//如果定时器还在,说明上一次延迟执行还没有完成,则不再执行
    timer = setTimeout(() => {
      fn.apply(this, arguments);
      timer = null;
    }, delay);
  };
}



防抖(debounce)

防抖:将几次操作合并为一次操作进行。

防抖(debounce)的中心思想在于:我会等你到底。在某段时间内,不管你触发了多少次回调,我都只认最后一次。

function debounce(fn: Function, delay: number) {
  let timer: any = null;

  return function () {
    if (timer) {
      clearTimeout(timer);//如果方法多次触发,则把上次记录的延迟执行代码清掉,重新开始
    }
    timer = setTimeout(() => {
      fn.apply(this, arguments);
      timer = null;
    }, delay);
  };
}



总结

防止事件频繁触发回调函数的方法有很多,其中防抖和节流是现在比较主流的处理方式。

节流和防抖动最大的区别就是,节流函数不管事件触发有多频繁,都会保证在规定时间内一定会执行一次真正的事件处理函数,而防抖动只是在最后一次事件后才触发一次函数。


最后一次编辑于  2023-07-11  
点赞 0
收藏
评论

1 个评论

  • 贝爷
    贝爷
    2023-08-15

    调用的时候怎么解决 this的问题呢


    2023-08-15
    赞同
    回复
登录 后发表内容