手机版

javascript防抖功能去抖详解

时间:2021-08-22 来源:互联网 编辑:宝哥软件园 浏览:

定义和解释

防抖功能去抖是指一个功能无论在一定时间内触发多少次回调,都只会执行最后一次。如果我们设置一个等待时间为3秒的函数,如果我们在这3秒内遇到一个函数调用请求,我们会重新计时3秒,直到新的3秒内没有函数调用请求,然后执行该函数,否则,我们会类比重新计时。

我们举一个小例子:假设乘坐公交车时,司机需要等最后一个人进入后才能关门。每次有新人进入,司机都会重置计时器,重新开始计数,再等一分钟再关门。如果在下一分钟内没有乘客上车,司机会认为所有乘客都已经上来了,会关上门发动汽车。

这时,“上车”是我们频繁操作事件,不断涌入的回调任务;“一分钟”是计时器,是司机决定“关门”的依据。如果有新的“乘客”上车,将被清除并重新计时;关门是最后要执行的功能。

如果还是看不懂,看下图就清楚多了。此外,单击此页面查看节流和防抖之间的视觉比较。其中,Regular是不做任何处理的情况,throttle是函数节流的结果(上一节介绍过),去抖是函数防抖的结果。

原则和实施

实现原理是使用定时器。当第一次执行某个功能时,会设置一个计时器。稍后调用时,发现定时器已经置位,则清除之前的定时器,重新设置新的定时器。如果有一个计时器没有被清除,当计时器结束时,该功能将被触发执行。

实施1

//实现1//fn是需要防抖处理的函数//wait是函数去抖的时间间隔(fn,Wait=50) {//通过闭包缓存一个定时器。idlet timer=null//作为函数返回去抖处理的结果//执行此返回函数(.args)。{//如果定时器已经设置,清除最后一个定时器if (timer) ClearTimeout(timer)//开始设置新的定时器,执行传入函数fn timer=settimeout (()={fn。计时器结束后应用(this,args)}。Wait)}}//DEMO//执行去抖函数返回新函数const better fn=去抖()=console.log('fn执行了防抖'),1000)//停止滑动1秒钟,然后执行函数()=console.log ('fn执行了防抖')document.addeventlistener(')

上面的实现方案可以解决大部分使用场景,但是如果你想在第一次触发回调事件的时候实现fn,就有点力不从心了。此时,让我们重写去抖函数,并添加第一次触发回调事件时立即执行的函数。

//实现2//immediate指示第一次是否立即执行函数去抖(fn,wait=50,Immediate){让timer=null返回函数(.args) {if (timer)清除超时(Timer)///-Timer){ fn。应用(this,args)}///-新零件End-Timer=SetTimeout (()={fn。apply (this,args)},Wait)}//DEMO//执行去抖函数返回一个新函数const better fn=去抖(()=console.log ('fn防抖被执行'),1000,true)//第一次触发滚动执行一次fn,函数fndocument。只有在停止滑动1秒钟后,才会执行addeventlistener ('scroll ',更好的fn)。实现原理简单。有必要判断传入的即时消息是真是假。另外,还要判断是否是第一次执行防抖功能。判断依然是计时器是否为空,所以才立竿见影!当定时器返回真时执行fn函数,即fn.apply(this,args)。

增强型节气门

现在考虑一种情况,如果用户的操作非常频繁,那么在设置的延迟时间结束之前会执行下一个操作,并且定时器会频繁清零和重新生成,因此函数fn不能一直执行,导致用户操作的响应延迟。

一个想法是将“油门”和“防抖”结合成一个增强的油门功能。关键是“计时器可以在等待时间内重新生成,但是一旦等待时间到了,就必须给用户一个响应”。这种组合可以解决上述问题。

在给出组合代码之前,让我们先回顾一下throttle函数,这在上一节中有详细描述。

//fn是要执行的函数//wait是时间间隔const throttle=(fn,Wait=50)={//上次执行fn的时间let previous=0//将throttle处理的结果作为函数返回给return function(.args) {//获取当前时间并将其转换为时间戳。单位毫秒let now=new Date()//将当前时间与上次执行函数的时间进行比较//如果大于等待时间,则将previous设置为当前时间并执行函数fnif(now-previous wait){ previous=now fn。apply (this,Args)}}}结合了油门和去抖代码,增强油门功能油门如下。新的逻辑是当当前触发时间和上次触发时间的时间差小于时间间隔时,设置一个新的定时器,相当于把去抖码放在小于时间间隔的部分。

//fn是要节流的函数//wait是时间间隔函数throttle (fn,wait) {//previous是最后一次执行fn//Timer是timer let previous=0,Timer=null//将节流处理的结果作为函数返回给return function(.args) {//获取当前时间并将其转换为时间戳。单位毫秒let now=新日期()////-为此触发操作设置新计时器。//定时器到期后,执行函数fn if(timer)clear time out(timer)timer=settimeout()={ previous=now fn。应用(这个,参数)}。wait)//-} else {//第一次执行//或者时间间隔超过设定的时间间隔,执行函数fnprevious=nowfn.apply(this,Args)} }//DEMO//执行throttle函数返回新函数const better fn=throttle(()=console . log(' fn throttle executed '),1000)//触发滚动第一次执行fn,每1秒执行函数fn。停止滑动1秒钟,然后执行功能fndocument。addeventlistener ('scroll ',最好是fn)。查看整个代码,您会发现这个想法与上一篇文章中介绍的在下划线中节流的实现想法非常相似。

下划线源代码分析

看完上面代码的基础版,感觉挺轻松的。现在,让我们学习如何用下划线实现去抖功能,学习一些优秀的想法,并直接加载代码和注释。源代码分析取决于下划线版本1.9.1的实现。

//这里的三个参数上面已经解释过了。_.去抖=func(func,wait,immediate) {//timeout表示timer //result表示func执行返回值var timeout,result;//定时器结束后//1。清空计时器,使其不影响下一个连续事件的触发。//2.稍后触发并执行func var=func(context,args){ time out=null;//判断if (args)过滤即时触发。//关联是_。delay和restargumentsif (args)结果=func.apply (context,args);};//将去抖处理的结果作为函数,返回var去抖=rest参数(function(args){ if(time out)clear time out(time out));If (immediate) {//首次触发后将设置超时。//根据超时是否为空,可以判断是否是第一次触发。超时;超时=setTimeout(稍后,等待);if(callNow)result=func . apply(this,args);} else {//设置定时器超时=_。延迟(稍后,等待,这个,args);}返回结果;});//添加并手动取消无界。cancel=function () {cleartimeout(超时);超时=null};返回去抖;};//执行func _函数。delay=restarguments(func(func,wait,args){ return settimeout(func(){ return func。根据给定的毫秒等待延迟应用(null,args));},等等);});与上面的基本实现相比,下划线具有以下功能。

1.func执行后,返回结果值

2.计时器结束后清除超时,这样就不会影响下一个连续事件的触发

3.增加了手动取消功能

4.当immediate为true时,只在第一次触发时执行,频繁触发回调后不执行

摘要

功能节流和防抖既是“闭包”,也是“高阶功能”。应用功能节流是指某个功能在某个时间间隔(例如3秒)内被执行一次。在这3秒内节流,忽略后来生成的函数调用请求,可以理解为养金鱼时拧紧水龙头放水。3秒内一滴“管道里的水”是一个回调任务,因为频繁的操作事件而不断涌入。它需要接受“水龙头”的安排。“水龙头”是控制水流量的节流阀。过滤无效的回调任务“滴水”意味着定期执行函数“3秒”。是“水龙头”决定“滴水”的依据。应用:监控滚动事件并添加节流功能后,将定期执行。实施方案一:用时间戳判断执行时间是否到了。记录最后一次执行的时间戳,然后在每次触发后执行回调,判断当前时间和最后一次执行时间的间隔是否达到时间差(Xms),如果是,执行,更新最后一次执行的时间戳,这样循环实现方案二:使用定时器,比如滚动事件刚触发时,打印一个hello world,然后设置一个1000ms的定时器,之后每次触发滚动事件,就触发回调。如果计时器已经存在,回调不会执行方法,直到计时器被触发,处理程序被清除,然后计时器函数被重置。防抖去抖是指无论回调被触发多少次,某个功能只执行一定时间内最后一次防抖。可以理解为司机在关门前等待最后一个人进入,每次都有新的人进入。驾驶员将重置计时器并重新开始计时。“乘客上车”是我们频繁操作事件的回调任务。“一分钟”是计时器,是司机决定“关门”的依据。如果一个新的“乘客”上车,它将被重置并再次计时。“关门”是最后一个要执行的功能应用:输入回调事件并添加防抖功能后,输入停止后实现方案只会触发一次:使用定时器,第一次执行该功能时设置一个定时器,发现已经设置定时器时清空之前的定时器,重新设置一个新的定时器。如果有一个计时器尚未清空,则在计时器结束后触发该功能执行。这就是本文的全部内容。希望对大家的学习有帮助,支持我们。

版权声明:javascript防抖功能去抖详解是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。