JS 防抖和节流,一篇文章讲透(原理,应用场景,调用已实现的)

一. 理解防抖(Debounce)和节流(Throttle)

防抖(Debounce)

防抖是指在一定时间内,如果事件被连续触发,则只执行最后一次触发的事件处理函数。如果在设定的时间间隔内事件又被触发,则重新计时。

比喻:就像电梯门,当有人进出时会一直保持开门状态,直到最后一个人进入后等待一段时间才关门。

节流(Throttle)

节流是指在一定时间内,无论事件被触发多少次,都只执行一次事件处理函数。

比喻:就像水龙头,无论你拧得多快,水流的速度都是固定的。

二. 手写实现

防抖实现

function debounce(fn, t) {
  let timer = null;
  return function(...args) {
    if (timer) clearTimeout(timer);
    timer = setTimeout(() => {
      fn.apply(this, args);
    }, t);
  };
}

 节流实现

 

function throttle(fn, delay) {
  let lastTime = 0;
  return function(...args) {
    const now = Date.now();
    if (now - lastTime >= delay) {
      fn.apply(this, args);
      lastTime = now;
    }
  };
}

// 使用定时器实现的版本
function throttle(fn, delay) {
  let timer = null;
  return function(...args) {
    if (!timer) {
      timer = setTimeout(() => {
        fn.apply(this, args);
        timer = null;
      }, delay);
    }
  };
}

三. 主要应用场景

防抖的应用场景

  1. 搜索框输入联想(等待用户停止输入后再发送请求)

  2. 窗口大小调整(等待调整结束后再计算布局)

  3. 表单验证(用户输入完再进行验证)

  4. 防止按钮重复点击

节流的应用场景

  1. 滚动加载更多(滚动过程中定期检查位置)

  2. 鼠标移动事件(如拖拽元素)

  3. 游戏中的按键操作(限制操作频率)

  4. 高频点击提交(如抢购按钮)

 

四. 各框架和库中的实现

Vue中的使用

Vue本身没有内置防抖/节流,但可以轻松实现:

// 在methods中
methods: {
  search: debounce(function(query) {
    // 搜索逻辑
  }, 500)
}

React中的使用

React同样没有内置,但可以使用hooks实现:

import { useCallback } from 'react';

function SearchComponent() {
  const debouncedSearch = useCallback(
    debounce(query => {
      // 搜索逻辑
    }, 500),
    []
  );
  
  return <input onChange={e => debouncedSearch(e.target.value)} />;
}

Lodash中的实现

Lodash提供了现成的_.debounce_.throttle

import _ from 'lodash';

// 防抖
const debouncedFn = _.debounce(fn, 300);

// 节流
const throttledFn = _.throttle(fn, 300);

现代浏览器API

较新的浏览器提供了requestIdleCallbackrequestAnimationFrame,也可以用于实现类似节流的效果:

function throttleWithRAF(fn) {
  let ticking = false;
  return function(...args) {
    if (!ticking) {
      requestAnimationFrame(() => {
        fn.apply(this, args);
        ticking = false;
      });
      ticking = true;
    }
  };
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值