快速理解防抖和节流

179 阅读3分钟

为什么需要防抖和节流?

  • 如果频繁的触发一个事件,每次触发都要执行一次函数,资源请求太频繁,会占用较多浏览器资源造成浏览器卡顿,响应速度跟不上触发速度,导致页面加载缓慢。

什么是防抖?

在事件被触发n秒后再执行回调,如果在这n秒内又被触发,则重新计时。简而言之就是指定时间内频繁触发同一事件,只会执行一次函数。

20210730-110042.gif

从这示例(非立即执行版防抖)我们可以得到以下结果:

  • 如果在1s内没有再次触发点击事件,那么就执行函数
  • 如果在1s内再次触发事件,那么当前的计时取消,重新开始计时
这里防抖又分为2种

立即执行版的防抖:触发事件后函数会立即执行,n 秒内再次触发事件不会执行,n秒后再次触发才会再次执行功能函数。

非立即执行版防抖:触发事件后 n 秒后才执行函数,如果在 n 秒内又触发了事件,则会重新计算函数执行时间。类似于王者荣耀的回城机制。

 /**
* 可以封装在工具类里面使用  util.js
* @desc 函数防抖---“立即执行版本” 和 “非立即执行版本” 的组合版
* @param func 执行函数
* @param wait 延迟执行时间(毫秒)
* @param immediate---true 表立即执行,false 表非立即执行
let timeout = null;
export const debounce = (func, wait = 500, immediate = false) => {
		// 清除定时器
		if (timeout !== null) clearTimeout(timeout);
		// 立即执行,此类情况一般用不到
		if (immediate) {
			var callNow = !timeout;
			timeout = setTimeout(function() {
				timeout = null;
			}, wait);
			if (callNow) typeof func === 'function' && func();
		} else {
			// 设置定时器,当最后一次操作后,timeout不会再被清除,所以在延时wait毫秒后执行func回调方法
			timeout = setTimeout(function() {
				typeof func === 'function' && func();
			}, wait);
		}
}


//页面方法里使用
import {debounce} from '@/util'
methods: {
     add(){
       debounce(()=>{
          /*写要干什么*/
       },1000,true)
    }
}

防抖应用场景

用户在输入框中连续输入一串字符时,可以通过防抖优化,只在输入完后,才执行查询的请求,这样可以有效减少请求次数,节约性能消耗。(当然节流也是可以的。看自己需求)

页面resize事件,常见于需要做页面适配的时候。需要根据最终呈现的页面情况进行dom渲染(这种情形一般是使用防抖,因为只需要判断最后一次的变化情况)

什么是节流?

如果指定时间内高频触发同一事件,那么在函数执行一次之后,该函数在指定的时间期限内不再执行,直至过了这段时间才重新生效。

节流又分为2种

立即执行版的节流(立即执行)

非立即执行版节流(延迟执行)

/**
* @desc 函数防抖---“立即执行版本” 和 “非立即执行版本” 的组合版
* @param func 执行函数
* @param wait 延迟执行时间(毫秒)
* @param immediate---true 表立即执行,false 表非立即执行
 export function throttle_merge(func,wait = 500,immediate=false){
    let flag = true;
    return function(...args){
      if(flag == true){
        let context = this
        flag = false
        immediate&& func.apply(context,args)
        setTimeout(() => {
          !immediate && func.apply(context,args)
          flag = true
        },wait)
      }
    }
  }

节流应用场景

监听滚动是否触底加载接口分页。每隔一段时间发一次 Ajax 请求,而不是在用户停下滚动页面操作时才去请求数据。这样的场景,就适合用节流技术来实现。

20210730-112105.gif

从这示例(立即执行版节流)我们可以得到以下结果:

  • 点击事件每1s执行一次。

总结

函数节流不管事件触发有多频繁,都会保证在规定时间内一定会执行一次真正的事件处理函数,而函数防抖只是在最后一次事件后才触发一次函数。