debounce和throttle是开发中常用的高阶函数。它们用于防止函数被频繁调用。换句话说,它们用于在一定时间内控制功能。执行多少次。在使用绑定等场景响应鼠标移动、窗口缩放、滚动等事件时,绑定函数触发的频率会非常频繁。如果处理函数稍复杂,需要更多的计算执行时间和资源,往往会出现延迟,甚至导致假死或僵硬的感觉。为了优化性能,这时候就需要使用debounce或者throttle。debounce和throttle防抖(debounce)的区别:多次触发,只有最后一次触发时,才执行目标函数。Throttle:限制目标函数调用的频率,例如:1s内不能调用两次。手写油门有两种实现方案:第一种是通过时间戳来判断执行时间是否到了,记录上次执行的时间戳,然后每次触发事件时执行回调,判断callback中当前时间戳与上次时间戳的距离执行时间戳的间隔是否达到时间差(Xms),如果是则执行,并更新上次执行的时间戳,以此类推。第二种方法是使用定时器。比如在scroll事件刚触发的时候,打印一个helloworld,然后设置一个1000ms的定时器,然后在每次scroll事件触发的时候触发回调。如果定时器已经存在,回调将不会执行该方法,直到定时器触发,处理程序被清除,然后定时器被重置。这里我们采用第一种方案来实现,通过闭包保存一个之前的变量,每次触发throttle函数时判断当前时间和之前时间的时间差。如果时间差小于等待时间,则忽略该事件触发。如果大于等待时间,则将previous设置为当前时间并执行函数fn。让我们一步一步地实施它。首先,用一个闭包保存之前的变量。constthrottle=(fn,wait)=>{//最后一次执行函数letprevious=0returnfunction(...args){console.log(previous)...}}执行完throttle函数后,一个新的函数将被返回,我们将其命名为betterFn。constbetterFn=function(...args){console.log(previous)...}betterFn函数可以获取前一个变量的值,也可以对其进行修改。BetterFn会在监听回调或者事件触发时执行,即betterFn()。因此,在这个新函数中判断当前时间和之前时间的时间差就足够了。constbetterFn=function(...args){letnow=+newDate();if(now-previous>wait){previous=now//执行fn函数fn.apply(this,args)}}结合上面两块code实现了节流功能,所以完整的实现如下。//fn是需要执行的函数//wait是时间间隔constthrottle=(fn,wait=50)=>{//上次执行fn的时间letprevious=0//返回throttle处理结果asafunctionreturnfunction(...args){//获取当前时间并将其转换为以毫秒为单位的时间戳letnow=+newDate()//将当前时间与上次函数执行的时间进行比较//如果是大于等待时间,设置previous为当前时间并执行函数fnif(now-previous>wait){previous=nowfn.apply(this,args)}}}//DEMO//执行throttle函数并返回newfunctionconstbetterFn=throttle(()=>console.log('fn函数执行完毕'),1000)//每10毫秒执行一次betterFn函数,但只有当时间差大于1000时才会fnsetInterval(betterFn,10)被执行
