手写一个防抖节流函数及其使用场景

防抖和节流是性能优化手段
什么是防抖? 防抖:单位时间内,频繁触发事件,只执行最后一次。 防抖的主要应用场景:
  • 搜索框搜索输入。只需用户最后一次输入完,再发送请求
  • 手机号、邮箱验证输入检测
什么是节流? 节流:单位时间内,频繁触发事件,只执行一次。 节流的主要应用场景:
  • 高频事件 例如 resize 事件、scroll 事件
  • 手机号、邮箱验证输入检测

相同点:

  • 都可以通过使用 setTimeout 来实现
  • 降低回调执行频率。节省计算资源

不同点:

  • 函数防抖,在一段连续操作结束后,处理回调,利用 clearTimeout 和 setTimeout 来实现。函数节流,在一段连续操作中,每一段时间只执行一次,频率较高的事件中使用来提高性能
  • 函数防抖关注一定时间连续触发的事件,只在最后执行一次,而函数节流一段时间内只执行一次

本质上是优化高频率执行代码的一种手段

如:浏览器的 resizescrollkeypressmousemove 等事件在触发时,会不断地调用绑定在事件上的回调函数,极大地浪费资源,降低前端性能

为了优化体验,需要对这类事件进行调用次数的限制,对此我们就可以采用throttle(抖流)和debounce(节防)的方式来减少调用频率

定义
  • 节流: n 秒内只运行一次,若在 n 秒内重复触发,只有一次生效
  • 防抖: n 秒后在执行该事件,若在 n 秒内被重复触发,则重新计时

一个经典的比喻:

想象每天上班大厦底下的电梯。把电梯完成一次运送,类比为一次函数的执行和响应

假设电梯有两种运行策略 debounce 和 throttle,超时设定为 15 秒,不考虑容量限制

电梯第一个人进来后,15 秒后准时运送一次,这是节流

电梯第一个人进来后,等待 15 秒。如果过程中又有人进来,15 秒等待重新计时,直到 15 秒后开始运送,这是防抖

代码
// 防抖函数
function debounce(func, delay) {
  let timer;
  return function () {
    const context = this;
    const args = arguments;
    clearTimeout(timer);
    timer = setTimeout(function () {
      func.apply(context, args);
    }, delay);
  };
}

// 节流函数
function throttle(func, delay) {
  let timer;
  return function () {
    const context = this;
    const args = arguments;
    if (!timer) {
      timer = setTimeout(function () {
        func.apply(context, args);
        timer = null;
      }, delay);
    }
  };
}

场景1:搜索框实时搜索

在这个场景中,我们希望用户在输入搜索关键字时,不会立即触发搜索请求,而是等待用户停止输入一段时间后才发起请求。这是一个典型的防抖用例

// HTML结构
<input type="text" id="searchInput">
<div id="searchResults"></div>

// JavaScript代码
const searchInput = document.getElementById("searchInput");
const searchResults = document.getElementById("searchResults");

function performSearch(query) {
  // 模拟搜索操作,实际中可以发起AJAX请求等
  searchResults.innerHTML = `正在搜索:${query}`;
}

const debouncedSearch = debounce(performSearch, 300); // 防抖处理搜索函数

searchInput.addEventListener("input", function () {
  const query = this.value;
  debouncedSearch(query); // 使用防抖函数处理输入事件
});

场景2:滚动事件

在这个场景中,我们希望用户滚动页面时,不会因为滚动事件频繁触发而导致性能问题。这是一个典型的节流用例。

// JavaScript代码
function handleScroll() {
  // 处理滚动事件,例如更新UI等
}

const throttledScroll = throttle(handleScroll, 200); // 节流处理滚动事件

window.addEventListener("scroll", throttledScroll); // 使用节流函数处理滚动事件

猜你喜欢

转载自blog.csdn.net/weixin_53818172/article/details/132674784