都在讲怎么写防抖,那么你知道怎么用防抖函数的吗

前言

说到防抖,相信做前端的没有谁不知道,甚至说到手写一个防抖函数,也基本是信手拈来。

js 复制代码
function debounce(fn, delay) {
  let timer;
  return function (...args) {
    if (timer) {
      clearTimeout(timer);
    }

    timer = setTimeout(() => {
      fn.apply(this, args);
    }, delay);
  };
}

使用场景

说到防抖,那还得提一嘴它的使用场景:

  1. 输入框监听用户输入,发送接口请求数据,是没必要没输入一个字符就请求一次的;
  2. 在处理窗口的 resize 事件时,也没必要没监听到变化就触发事件执行;

以上是经典的使用场景,当然,在我们需要限制触发的次数时,都可以考虑使用防抖函数。

遇到的问题

在我自己以前使用防抖的场景中,也基本是上述的两个场景。直接 addEventListener('resize', debounce(fn, 300)),一切都用的理所当然。

然而在最近修改一个问题时,确遇到了点麻烦。

我们系统接入了 qiankun 微前端框架,在频繁切换菜单的时候,会出现几个菜单疯狂的来回跳转,此时只有刷新页面或者等页面崩溃再刷新操作。

在解决这问题的时候,最开始也是准备从 qiankun 这个框架入手,想着是不是因为切换太频繁,导致子应用没有卸载成功,出现了与主应用抢占 URL 的现象。但是经历了各种尝试,发现子应用是卸载成功了的,也没定位到到底是哪儿一直在触发切换URL,或许这得去仔细研究下 qiankun 的源码才能知道了,因为不切换子应用菜单时,是没问题的。但是这个问题又比较紧急,给不了时间去研究,那只能看能不能另辟蹊径了。于是,防抖函数进入了我的脑海。

因为正常情况下,是没有用户会快速频繁切换多个菜单的(排除"找茬"的测试),或者也会有用户这样操作,但我相信这只是会极个别的。因此,在切换菜单时,增加一个防抖处理,是不是也能解决这个问题呢?

于是,我开始在菜单切换的地方开始加入防抖。一开始,我的代码是这样的:

html 复制代码
... (click)="changeTab($event)"
js 复制代码
function changeTab($event) {
  debounce(jump, 100);
}

function jumpTab(tabId) {
  xxx;
}

刚写完,发现不对啊,那个 jumpTab 是需要参数的,但是 changeTab 中没有传参数,jumpTab 是不知道跳到哪个菜单的。于是,我想当然的进行了修改:

js 复制代码
function changeTab($event) {
  debounce(jump($event), 100);
}

改完一执行,发现菜单是可以跳转的,但是那个防抖没用上,在快速切换后,菜单会沿着点击的顺序挨个跳转,还是不行。为啥会不行呢,我去 debounce 函数中打断点一看,每次执行 changeTab 事件时,都在重新执行一遍 debounce,而且这个地方传入的是 jump($event),本身就会执行一次,相当于是这个 debounce 根本就没用。

然后也试过这样写:

js 复制代码
function changeTab($event) {
  debounce(jump, 100)($event);
}

最后结果同上,并没有实现防抖功效。

原本以为自己对防抖函数也算是理解了,但没想到这换个地方用,就不对了。然后又看了一遍 debounce 函数的实现,它是利用了闭包的特质,debounce 返回一个函数,后续的调用实际上都是调用的返回的这个函数,而不是我这种每次都在重新调用 debounce 函数。

那么思路就有了,再定义一个函数,将 debounce 函数执行并返回,在 changeTab 中执行这个新定义的函数。

js 复制代码
function debounceFn = () => debounce(jump, 100)
function changeTab($event) {
  debounceFn($event);
}

这样就能保证每次 changeTab 都是执行的同一个函数。

后续

当然这个问题的解决方法也算是一种取巧,还是得看下为啥会出现这个问题的根因。另一方面,通过这个问题,也加深了自己对防抖函数的认知。

相关推荐
安全系统学习1 小时前
系统安全之大模型案例分析
前端·安全·web安全·网络安全·xss
涛哥码咖1 小时前
chrome安装AXURE插件后无效
前端·chrome·axure
OEC小胖胖1 小时前
告别 undefined is not a function:TypeScript 前端开发优势与实践指南
前端·javascript·typescript·web
行云&流水2 小时前
Vue3 Lifecycle Hooks
前端·javascript·vue.js
Sally璐璐2 小时前
零基础学HTML和CSS:网页设计入门
前端·css
老虎06272 小时前
JavaWeb(苍穹外卖)--学习笔记04(前端:HTML,CSS,JavaScript)
前端·javascript·css·笔记·学习·html
灿灿121382 小时前
CSS 文字浮雕效果:巧用 text-shadow 实现 3D 立体文字
前端·css
烛阴2 小时前
Babel 完全上手指南:从零开始解锁现代 JavaScript 开发的超能力!
前端·javascript
AntBlack3 小时前
拖了五个月 ,不当韭菜体验版算是正式发布了
前端·后端·python
31535669133 小时前
一个简单的脚本,让pdf开启夜间模式
前端·后端