四. debounce 函数的实现
我们只有一个函数需要防抖的话其实这样看着还行,但是现在有10个,100函数呢?我难道一个个这样写吗?nonono,程序员都是很懒滴~是不可能写重复的低质量代码的。所以聪明的你可能会想到会写一个生产 自我防抖 函数的函数。没错,引出我们今天的主角 debounce。
好的,铺垫了这么久,也该敲敲代码了。
我们先在 utils
文件夹下创建 debounce.ts
的文件来放我们的防抖函数。顾名思义。
既然是包装函数,那么你得给它一个东西,它才能帮你包装吧。那么这个函数应该接受一个参数,这个参数应该也是一个函数。(后期我们需要把上面我们写到的请求后端的函数, toSearch
函数给放进去)
⚠️注意:接下来是本文的第二个重点。这里我们需要用到高阶函数。让我们先看看高阶函数的定义是什么。
不要怕,它并不是像数学和高等数学的差距那样!如果你是第一次听到这个名词,你可以这样理解:就像你送别人礼物,你为了好看,你会把这个物品给用精美的包装给包一层。那么我们的 防抖 函数在这里的作用其实就是帮你把这个函数包装一下的意思,它并不会直接影响这个函数的内部逻辑,就像你的礼物包装一层包装纸🎁后,它本身是没有发生任何变化的。
所以在这里我们应该返回一个函数来存放我们真正的业务代码。(为了方便写成了匿名函数,你也可以先在函数内部使用 function关键词声明一个带名字的函数 最后返回,效果是一样的)
然后直接把我们上一步实现的自我防抖函数内部的逻辑复制过来。
就是这么简单~
哦,稍等,别忘了把 setTimeout
里的 console.log('发请求')
替换成我们的参数 fn
。
接下来去 app.vue 里引入这个函数。
五. 闭包和 debounce 的关系
等等,别着急。我大概能能猜到你会这样使用。
然后抱着这个毫无反应的页面怀疑人生。
在这里我需要额外说明一下,这种写法在 react 中可以正确执行的。
主要原因有兴趣的读者可以自行去搜索一下,还是很有意思的~
回到 Vue,还记得我们最开始的写法吗?
我们是在这个组件内定义了一个《相当于这个组件的“全局变量”》。那么当我在这个页面有多个需要防抖的函数的话,就会造成这样的场面。
极度不优雅和难以维护。
那怎么办呢?这里我们就需要用到闭包函数。 闭包不另开一篇文章讲解是讲不完的,并且阮一峰阮大的闭包讲解的已经很好了,我就不献丑了)
对于现在的场景简单来说,你可以这样理解。闭包相当于在自身的范围内,通过在函数内部引用自己的 变量timerID 来达成变量 timeID 在 debounce 函数执行后并不会被马上销毁的目的。
那么我们正确的写法就是,用一个变量来接收 debounce
返回的那个函数。并且此时此刻,已经同步生成了一个暂时不会被销毁的 timeID 来保存我们 setTimeout
生产的那个 id身份证。(这里可能不是特别好理解,需要读者自行去了解闭包的机制)
测试一下:
总结:
如果读者能够细心品文本篇文章的细节,你可能会自然而然的理解节流的原理是什么。节流相关知识我之前也是通俗易懂的用游戏技能冷却🎮带你去理解原理是什么。有兴趣的读者可以自行查阅~
特别感谢:
@林水溶君
@Baoyuan0808
最后感谢两位大佬对我写本文提供的思路和技术指导。🎁