防抖与节流常见的几种实现方式

转自:http://www.fly63.com/article/detial/8038

防抖与节流常见的几种实现方式

防抖

在限制的时间内持续触发事件的时候,函数是完全不执行的

非立即执行版,等最后一次触发结束的一段时间之后,再去执行

function debounce(func, delay) {
  let timeout
  return function() {
    clearTimeout(timeout) // 如果持续触发,那么就清除定时器,定时器的回调就不会执行。
    timeout = setTimeout(() => {
      func.apply(this, arguments)
    }, delay)
  }
}

立即执行版

function debounce(func,wait) {
    let timeout;
    return function () {
        let context = this;
        let args = arguments;

        if (timeout) clearTimeout(timeout);

        let callNow = !timeout;
        timeout = setTimeout(() => {
            timeout = null;
        }, wait)

        if (callNow) func.apply(context, args)
    }
}

双剑合璧版

/**
 * @desc 函数防抖
 * @param func 函数
 * @param wait 延迟执行毫秒数
 * @param immediate true 表立即执行,false 表非立即执行
 */
function debounce(func,wait,immediate) {
    let timeout;

    return function () {
        let context = this;
        let args = arguments;

        if (timeout) clearTimeout(timeout);
        if (immediate) {
            var callNow = !timeout;
            timeout = setTimeout(() => {
                timeout = null;
            }, wait)
            if (callNow) func.apply(context, args)
        }
        else {
            timeout = setTimeout(function(){
                func.apply(context, args)
            }, wait);
        }
    }
}

 

节流

节流的意思是让函数有节制地执行,而不是毫无节制的触发一次就执行一次,在一段时间内,只执行一次。

 function throttle(func, deley) {
    let run = true
    return function () {
      if (!run) {
        return  // 如果开关关闭了,那就直接不执行下边的代码
      }
      run = false // 持续触发的话,run一直是false,就会停在上边的判断那里
      setTimeout(() => {
        func.apply(this, arguments)
        run = true // 定时器到时间之后,会把开关打开
      }, deley)
    }
  }
### 防抖节流的概念 防抖(Debouncing)是指当某个事件被触发时,在一定时间内如果该事件再次被触发,则重新计时,只有在指定的时间间隔内不再触发此事件时才会执行对应的回调函数[^1]。这种机制可以有效减少高频事件的调用次数。 节流(Throttling)则是指在一个特定时间范围内只允许某件事情发生一次或者有限几次。即使事件频繁触发,也会按照设定好的固定频率来执行相应的逻辑[^2]。 --- ### 防抖节流的区别 两者的根本区别在于它们控制事件触发的方式不同: - **防抖**关注的是最后一次触发后的延迟效果,即等待一段时间后再执行操作。 - **节流**则是在连续多次触发的情况下,按固定周期执行动作,忽略多余的触发请求[^4]。 --- ### 防抖的具体实现方式 以下是基于 JavaScript 的一种常见防抖函数实现方法: ```javascript function debounce(func, delay) { let timer; return function (...args) { clearTimeout(timer); timer = setTimeout(() => func.apply(this, args), delay); }; } ``` 上述代码通过 `setTimeout` 和 `clearTimeout` 来管理定时器对象 `timer`,从而确保每次新事件到来都会清除之前的延时任务并设置新的延时任务[^3]。 #### 使用示例 假设我们需要监听窗口大小变化,并希望仅在调整结束后才更新布局: ```javascript window.addEventListener('resize', debounce(function () { console.log('Window resized'); }, 300)); ``` --- ### 节流的具体实现方式 下面是一个典型的节流函数定义: ```javascript function throttle(func, limit) { let lastCall = 0; return function(...args){ const now = new Date().getTime(); if(now - lastCall >= limit){ lastCall = now; func.apply(this, args); } }; } ``` 这里利用当前时间和上一次成功运行之间的时间差判断是否应该继续执行目标功能。 #### 应用实例 对于滚动条位置监控来说,我们可以这样写: ```javascript window.addEventListener('scroll', throttle(function() { console.log('Scrolling...'); }, 200)); ``` --- ### 实际应用场景分析 无论是防抖还是节流都广泛应用于各种前端开发场景之中,具体如下表所示: | 功能需求 | 推荐方案 | |----------|----------------| | 输入框自动补全提示 | 防抖 | | 页面无限加载更多数据 | 节流 | | 缩放浏览器视窗尺寸检测 | 防抖/节流均可考虑依据业务复杂度决定优先级 | 例如,在输入框实时查询建议列表的时候采用防抖策略能够显著降低服务器压力;而针对持续性的滚屏行为监测更适合运用节流手段以维持流畅体验同时节省资源开销。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值