防抖与节流

Lirioing2025/07/09JavaScriptFEJavaScript

防抖(Debounce)和节流(Throttle)是前端开发中常用的两种优化手段,主要用于控制高频率触发的事件,避免过多的计算或者操作影响性能。

防抖(Debounce)

在事件被触发后,延迟指定时间才执行事件的处理函数,如果这段时间内时间再次被触发,则重新计时。

工作原理:

  1. 当事件被处罚时,设定一个定时器
  2. 如果在定时器到期前事件再次被处罚,则清除之前的定时器并重新设置
  3. 只有当事件停止触发切定时器到期后,目标函数才会执行

典型应用场景:

  • 搜索框输入(等待用户停止输入后再发送请求)
  • 窗口大小调整事件
  • 表单验证(等用户完成输入后再验证)

代码示例

/**
 * 防抖原理:一定时间内,只有最后一次操作,再过wait毫秒后才执行函数
 * 
 * @param {Function} func 要执行的回调函数 
 * @param {Number} wait 延时的时间
 * @param {Boolean} immediate 是否立即执行 
 * @return null
 */
let timeout = null;
export function 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);
	}
}

使用

<view class="debounce" @tap="$u.debounce(btnAClick, 500)"></view>

<script setup>
const toNext => {
...
}
...
debounce(toNext, 500)
...
</script>

节流(Throttle)

在一段时间内只允许时间处理函数执行一次,无论事件触发了多少次

工作原理:

  1. 当事件第一次触发式,执行函数并记录时间
  2. 在指定的时间间隔内,忽略所有后续触发
  3. 时间间隔过后,再次触发是会执行函数并重复上述过程

典型应用场景:

  • 鼠标移动事件(当鼠标移动时,每隔一定时间执行一次处理函数)
  • 滚动事件处理(当用户滚动页面时,每隔一定时间执行一次处理函数)
  • 防止按钮重复点击

代码示例

/**
 * 节流原理:在一定时间内,只能触发一次
 *
 * @param {Function} func 要执行的回调函数
 * @param {Number} wait 延时的时间
 * @param {Boolean} immediate 是否立即执行
 * @return null
 */
let timer;
let flag;
export function throttle(func, wait = 500, immediate = true) {
  if (immediate) {
    if (!flag) {
      flag = true
      // 如果是立即执行,则在wait毫秒内开始时执行
      typeof func === 'function' && func()
      timer = setTimeout(() => {
        flag = false
      }, wait)
    }
  } else if (!flag) {
    flag = true
    // 如果是非立即执行,则在wait毫秒内的结束处执行
    timer = setTimeout(() => {
      flag = false
      typeof func === 'function' && func()
    }, wait)
  }
}

使用

<view class="throttle" @click="throttle(handeSave, 1000)">提交</view>


<script setup>
const toNext => {
...
}
...
throttle(toNext, 500)
...
</script>

总结

  • 如果需要在事件完全停止触发后才执行处理函数,使用防抖。

  • 如果需要在时间频繁触发是控制执行频率,使用节流。

  • 在实际开发中,可以根据具体需求选择合适的方式。(防止按钮重复点击,也可以给按钮加一个loading状态。)

上次更新 2025/7/9 16:58:23