JavaScript:防抖与节流

本文介绍了JavaScript中的防抖和节流技术,这两种策略用于限制频繁事件回调的执行次数,以提高性能并减少资源消耗。防抖在用户停止触发后执行,而节流确保在固定时间段内只执行一次。
摘要由CSDN通过智能技术生成

在JavaScript中,防抖(debounce)和节流(throttle)是两种优化函数调用频率的策略,它们主要用于限制频繁触发的事件回调函数执行次数,以防止过多不必要的计算和网络请求,从而提高性能并减少资源消耗。

防抖(Debounce)

防抖的核心思想是:当连续快速触发同一事件时,只有在最后一次触发后的一段时间内没有再次触发该事件,才会执行对应的处理函数。例如,在输入框搜索场景下,用户在短时间内连续输入字符,通过防抖可以确保在用户停止输入一段时间后再发送搜索请求

实现原理通常是设置一个定时器,每次事件触发时都会清除上一次的定时器并重新设置一个新的定时器。如果在指定的时间间隔内又有新的事件触发,则会继续取消当前定时器并重置。直到最后一定时间间隔内无新事件触发时,之前设置的最后一个定时器到期后才真正执行回调函数。

//func 是需要被防抖处理的函数,wait 是等待时间(单位为毫秒)
function debounce(func, wait) {

//在外部作用域中定义一个变量 timeoutId 用于存储定时器ID,以便后续取消已设置的定时器。
 let timeoutId;
 
 return function (...args) {
   //清除之前已经设定好的定时器
   if (timeoutId) clearTimeout(timeoutId);
   //重新设置一个新的定时器,延迟指定的 wait 毫秒后执行回
   timeoutId = setTimeout(() => {
     //调用原始的 func 函数
     func.apply(this, args);
   }, wait);
 };
}

// 示例:在窗口调整大小时触发防抖函数
window.addEventListener('resize', debounce(function handleResize() {
 console.log('Window resized');
}, 300)); // 只有在用户停止调整窗口大小300毫秒后才会打印日志

节流 (Throttle)

节流则是另一种限制频率的方式,它允许事件在固定时间段内只执行一次。即使事件被频繁触发,但在每个时间段内只会执行一次操作。这样可以保证无论事件触发多么频繁,函数至少每过一段时间就会执行一次。

例如,在窗口滚动事件监听中,使用节流可以确保在用户滚动过程中每隔一定时间(比如每秒)更新一次视图位置,而不是在滚动期间不断刷新,从而避免过度渲染导致的性能问题。

实现节流的方法通常包括设置定时器,并在每一次事件触发时检查是否需要重新开始计时或直接执行回调函数。

function throttle(func, wait) {
  let lastExecutionTime = 0;//存储最后一次执行该函数的时间戳
  let timerId;//存储定时器ID以便在必要时取消已设置的定时器

  return function (...args) {
    const now = Date.now();
    //如果当前时间与上次执行时间差大于等于等待时间 wait,则直接执行原函数
    if (now - lastExecutionTime >= wait) {
      func.apply(this, args);
      lastExecutionTime = now;
    } else if (!timerId) {
      //创建一个新的定时器,延迟时间为wait - (now - lastExecutionTime)即wait时间内剩余时间
      timerId = setTimeout(() => {
      //执行原函数,并在执行完成后清空 timerId,同时将当前时间更新到 lastExecutionTime
        func.apply(this, args);
        timerId = null;
        lastExecutionTime = Date.now();
      }, wait - (now - lastExecutionTime));
    }
  };
}

// 示例:在窗口滚动时触发节流函数
window.addEventListener('scroll', throttle(function handleScroll() {
  console.log('Window scrolled');
}, 500)); // 在滚动期间每过至少500毫秒会打印一次日志,即使滚动事件触发更频繁

总结来说,防抖更关注于限制最后一次操作之后的重复操作,而节流则关注于控制函数在一个时间段内的执行次数。

注:
.apply()方法用于调用一个函数,并允许传入一个数组(或类数组对象)作为参数列表,同时也可以指定函数执行时的上下文(this值)

function add(a, b) {
  return a + b;
}

let numbers = [3, 5];
console.log(add.apply(null, numbers)); // 输出:8

// 或者使用数组字面量作为参数
console.log(add.apply(null, [3, 5])); // 输出:8

// 使用上下文
let obj = { value: 10 };
let multiply = function(a) {
  return this.value * a;
};
console.log(multiply.apply(obj, [2])); // 输出:20
  • 16
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

待煎的前端

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值