Web前端   发布时间:2019-10-13  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了函数去抖(debounce)与 函数节流(throttle)大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。

以下场景往往由于事件频繁被触发,因而频繁执行DOM操作、资源加载等重行为,导致UI停顿甚至浏览器崩溃。

1. window对象的resize、scroll事件

2. 拖拽时的mousemove事件

3. 射击游戏中的mousedown、keydown事件

4. 文字输入、自动完成的keyup/keypress事件

实际上对于window的resize事件,实际需求大多为停止改变大小n毫秒后执行后续处理;而其他事件大多的需求是以一定的频率执行后续处理。针对这两种需求就出现了debounce和throttle两种解决办法。

一、什么是debounce

1、定义:

如果用手指一直按住一个弹簧,它将不会弹起直到你松手为止。

也就是说当调用动作n毫秒后,才会执行该动作,若在这n毫秒内又调用此动作则将重新计算执行时间。

接口定义:

{function} 请求关联函数,实际应用需要调用的函数 * @param delay {number} 空闲时间,单位毫秒 * @return {function} 返回客户调用函数

2、简单实现:

{Function} 实际要执行的函数 * @param delay {number} 延迟时间,也就是阈值,单位是毫秒(ms) * * @return {Function} 返回一个“去弹跳”了的函数 function debounce(fn,delay) {

<span style="color: #008000">//<span style="color: #008000"> 定时器,用来 setTimeout
<span style="color: #0000ff">var<span style="color: #000000"> timer

<span style="color: #008000">//<span style="color: #008000"> 返回一个函数,这个函数会在一个时间区间结束后的 delay 毫秒时执行 fn 函数
<span style="color: #0000ff">return<span style="color: #000000"> function () {

</span><span style="color: #008000"&gt;//</span><span style="color: #008000"&gt; 保存函数调用时的上下文和参数,传递给 fn</span>
<span style="color: #0000ff"&gt;var</span> context = <span style="color: #0000ff"&gt;this</span>
<span style="color: #0000ff"&gt;var</span> args =<span style="color: #000000"&gt; arguments

</span><span style="color: #008000"&gt;//</span><span style="color: #008000"&gt; 每次这个返回的函数被调用,就清除定时器,以保证不执行 fn</span>

<span style="color: #000000"> clearTimeout(timer)

</span><span style="color: #008000"&gt;//</span><span style="color: #008000"&gt; 当返回的函数被最后一次调用后(也就是用户停止了某个连续的操作),
</span><span style="color: #008000"&gt;//</span><span style="color: #008000"&gt; 再过 delay 毫秒就执行 fn</span>
timer =<span style="color: #000000"&gt; setTimeout(function () {
  fn.apply(context,args)
},delay)

}
}

其实思路很简单,debounce返回了一个闭包,这个闭包依然会被连续频繁地调用,但是在闭包内部,却限制了原始函数fn的执行,强制fn只在连续操作停止后只执行一次。

debounce的使用方式如下:

$(document).on(E) { },))
$().on(E) { },))

二、什么是throttle

1、定义

如果将水龙头拧紧直到水是以水滴的形式流出,那你会发现每隔一段时间,就会有一滴水流出。

  也就是会说预先设定一个执行周期,当调用动作的时刻大于等于执行周期则执行该动作,然后进入下一个新周期。

接口定义:

{number} 延迟时间,单位毫秒 * @param action {function} 请求关联函数,实际应用需要调用的函数 * @return {function} 返回客户调用函数

2、简单实现

{Function} 实际要执行的函数 * @param delay {number} 执行间隔,单位是毫秒(ms) * * @return {Function} 返回一个“节流”函数 {

<span style="color: #008000">//<span style="color: #008000"> 记录上次执行的时间
<span style="color: #0000ff">var<span style="color: #000000"> last

<span style="color: #008000">//<span style="color: #008000"> 定时器
<span style="color: #0000ff">var<span style="color: #000000"> timer

<span style="color: #008000">//<span style="color: #008000"> 默认间隔为 250ms
threshhold || (threshhold = <span style="color: #800080">250<span style="color: #000000">)

<span style="color: #008000">//<span style="color: #008000"> 返回的函数,每过 threshhold 毫秒就执行一次 fn 函数
<span style="color: #0000ff">return<span style="color: #000000"> function () {

</span><span style="color: #008000"&gt;//</span><span style="color: #008000"&gt; 保存函数调用时的上下文和参数,传递给 fn</span>
<span style="color: #0000ff"&gt;var</span> context = <span style="color: #0000ff"&gt;this</span>
<span style="color: #0000ff"&gt;var</span> args =<span style="color: #000000"&gt; arguments

</span><span style="color: #0000ff"&gt;var</span> now = +<span style="color: #0000ff"&gt;new</span><span style="color: #000000"&gt; Date()

</span><span style="color: #008000"&gt;//</span><span style="color: #008000"&gt; 如果距离上次执行 fn 函数的时间小于 threshhold,那么就放弃
</span><span style="color: #008000"&gt;//</span><span style="color: #008000"&gt; 执行 fn,并重新计时</span>
<span style="color: #0000ff"&gt;if</span> (last &amp;&amp; now < last +<span style="color: #000000"&gt; threshhold) {
  clearTimeout(timer)

  </span><span style="color: #008000"&gt;//</span><span style="color: #008000"&gt; 保证在当前时间区间结束后,再执行一次 fn</span>
  timer =<span style="color: #000000"&gt; setTimeout(function () {
    last </span>=<span style="color: #000000"&gt; now
    fn.apply(context,args)
  },threshhold)
</span><span style="color: #008000"&gt;//</span><span style="color: #008000"&gt; 在时间区间的最开始和到达指定间隔的时候执行一次 fn</span>
} <span style="color: #0000ff"&gt;else</span><span style="color: #000000"&gt; {
  last </span>=<span style="color: #000000"&gt; now
  fn.apply(context,args)
}

}
}

原理也不复杂,相比debounce,无非是多了一个时间间隔的判断,其他的逻辑基本一致。throttle的使用方式如下:

$(document).on(E) { },))

throttle常用的场景是限制resizescroll的触发频率

总结:

debounce强制函数在某段时间内只执行一次,throttle强制函数以固定的速率执行。在处理一些高频率触发的 DOM 事件的时候,它们都能极大提高用户体验。

大佬总结

以上是大佬教程为你收集整理的函数去抖(debounce)与 函数节流(throttle)全部内容,希望文章能够帮你解决函数去抖(debounce)与 函数节流(throttle)所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。
标签: