防抖和节流(较全&可体验)

防抖(debounce)

概念

事件被触发经过单位时间(delay)后再执行回调,如果在单位时间内又被触发,则重新计时。

防抖函数

const debounce = (cb, delay = 1000) => {
  let timer = null;
  return function (...args) {
    const context = this;
    if (timer) clearTimeout(timer);
    timer = setTimeout(() => {
      cb.apply(context, args);
      timer = null;
    }, delay);
  }
}

若延迟delay设置为1000(默认值),则cb(回调函数)只会在停止触发1s后执行,如果一直不断地触发,则回调函数始终不执行。

使用

下面是一个简单的使用示例,后续介绍的防抖和节流函数的使用方式也是相似的。

const callback = () => {      
  console.log(Math.random());
}
const handle = debounce(callback, 1000);
window.addEventListener('scroll', handle);

防抖函数(第一次触发会立即执行)

const debounceImmediate = (cb, delay = 1000, immediate = true) => {
  let timer = null;
  return function (...args) {
    const context = this;
    const execNow = immediate && !timer;
    if (timer) clearTimeout(timer);
    timer = setTimeout(() => {
      cb.apply(context, args);
      timer = null;
    }, delay);
    execNow && cb.apply(this, args);
  }
}

当设置immediate=true(默认值)、delay=1000(默认值)时,第一次触发会立即执行回调函数。后续执行和普通的防抖函数一样,只有在停止触发1s后回调函数才会执行,如果还是一直不断地触发,则回调函数始终不执行。

节流(throttle)

概念

规定在单位时间(delay)内,只能触发一次函数。如果单位时间内多次触发函数,只会执行一次回调。

节流函数(使用时间戳)

const throttleUseTimeStamp = (cb, delay = 1000) => {
  let startTime = Date.now();
  return function(...args) {
    const context = this;                    
    const now = Date.now();       
    if (now - startTime >= delay) {
        cb.apply(context, args);
        startTime = Date.now();        
    }
  } 
}

若delay=1000,则在1s内只会执行一次回调函数。

节流函数的实现(使用定时器)

const throttleUseTimer = (cb, delay) => {
  let timer = null;
  return function(...args) {
    const context = this;
    if (!timer) {
      timer = setTimeout(() => {
        cb.apply(context, args);      
        timer = null;      
      }, delay);  
    } 
  }
}

若delay=1000,则在1s内只会执行一次回调函数。

节流函数的实现(第一次触发立即执行,最后一次触发也会执行)

const throttleExecMore = function(cb, delay) {
  let timer = null; 
  let startTime = Date.now();
  return function(...args) {        
    const curTime = Date.now(); 
    const remaining = delay - (curTime - startTime); 
    const context = this;           
    timer && clearTimeout(timer);
    if (remaining <= 0) {
      // 第一次触发执行               
      cb.apply(context, args);              
      startTime = Date.now();         
    } else {
      // 最后一次触发也会执行             
      timer = setTimeout(() => {
        cb.apply(context, args);
        timer = null;
      }, remaining);          
    }
  }
}

第一次触发会立即执行回调函数,最后一次触发也会执行一次回调函数。

亲自体验

将前面介绍的5种防抖和节流函数分别应用在5个输入框的onChange事件的监听上,delay值统一设置为1000,快速输入1111得到结果如下:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-w0MXcp9m-1572689953273)(https://mfaying.github.io/static/images/防抖和节流/1.jpg)]
完全符合我们前面的分析。

如果不加防抖、节流控制,得到结果将是:

1
11
111
1111

触发了4次回调函数。

体验防抖和节流 (http://47.92.166.108:3000/blog/index.html#/tutorials/throttle-and-debounce)

体验网址二维码:

应用场景举例

防抖

  1. 搜索联想,在不断输入值时节约请求资源。
  2. 窗口resize事件

节流

  1. 鼠标不断点击,单位时间内只触发一次
  2. 滚动到底部加载更多

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在React应用开发中,可以通过使用React Hook机制来更方便地实现防抖节流功能。防抖函数(Debounce)可以用于在用户输入时延迟执行某个操作,以避免频繁触发操作。通过设置一个定时器,在指定的时间内没有再次触发操作时,才执行相应的逻辑。节流函数可以用于限制某个操作的执行频率,无论用户多快地触发操作,操作的逻辑都会按照设置的间隔时间执行。在React中使用节流函数可以通过设置定时器,在指定的时间间隔内只执行一次操作。 对于非受控组件,上述方式比较适用。如果需要在受控组件中实现防抖节流功能,可以采用React Hooks机制。通过useState Hook来定义一个state变量来存储输入框的值,然后通过useEffect Hook来监听该state变量的变化。当输入框的值发生变化时,可以通过设置一个定时器来延迟执行异步请求操作。在这种情况下,可以将防抖节流功能结合起来使用,以达到更好的用户体验。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [一文搞懂如何在 React 中使用 防抖Debounce)和 节流(Throttle)](https://blog.csdn.net/weixin_53312997/article/details/129248753)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值