浅聊函数防抖与节流

海军
• 阅读 2757

浅聊函数防抖与节流

防抖(debounce)

所谓防抖,就是指触发事件后 n 秒后才执行函数,如果在 n 秒内又触发了事件,则会重新计算函数执行时间。

防抖类型分为

  1. 非立即执行版
  2. 立即执行版
  3. 合成版本 防抖

防抖应用场景

  • 登录、发短信等按钮避免用户点击太快,以致于发送了多次请求
  • 调整浏览器窗口大小时,resize 次数过于频繁,造成计算过多,此时需要一次到位
  • 文本编辑器实时保存,当无任何更改操作一秒后进行保存

非立即执行版

非立即执行版的意思是触发事件后函数不会立即执行,而是在 n 秒后执行,如果在 n 秒内又触发了事件,则会重新计算函数执行时间。

/**
 * @description: 
 * @param {*} func 触发的事件
 * @param {*} wait 多少时长才执行事件
 * @return {*}
 */
        function debounce(func, wait) {
            let timeout;
            return function(){
                // 获取当前作用域和参数
                const context = this;
                const args = [...arguments] 
                // 如果当前timeout 存在
                // 清空定时器,再次等待wait时间过后再次执行事件
                if(timeout) clearTimeout(timeout)
                // 定时执行 传递进来的事件
                timeout = setTimeout(()=>{
                    func.apply(context,args)
                },wait)  
            }
        }

立即执行版本

立即执行版的意思是触发事件后函数会立即执行,然后 n 秒内不触发事件才能继续执行函数的效果。

function debounce(func,wait) {
  let timeout;
  return function () {
      const context = this;
      const args = [...arguments];
      if (timeout) clearTimeout(timeout);
      const callNow = !timeout;
      timeout = setTimeout(() => {
          timeout = null;
      }, wait)
      if (callNow) func.apply(context, args)
  }
}

代码解析

当 执行 debounce 函数时, 第一次进来时,timeout 为false,所以 callNow 的值 为 true ,那么它会立即执行 func 函数,这时 timeout 的值 为 true , 当 timeout 值为true 时, 会执行 清空定时器,此时 timeout 又为 false 了 , 这时 callNow 又 为 true ,再次执行 func 函数。

一直循环这样的操作:

timeoutfalse 时,会立刻执行 func 函数。

timeouttrue 时,它会执行clearTimeOut ,这时timeout 又为 false, 而 callNow = ! timeout , 就会立刻执行 func 函数了。

合成版本 防抖

通过传递 Boolean 来决定执行哪种版本。

  • true 为立即执行版
  • false 为非立即执行版本

debounce(func,1000,true)

/**
 * @desc 函数防抖
 * @param func 函数
 * @param wait 延迟执行毫秒数
 * @param immediate true 表立即执行,false 表非立即执行
 */
function debounce(func, wait, immediate) {
  let timeout;
  return function () {
    const context = this;
    const args = [...arguments];
    if (timeout) clearTimeout(timeout);
    if (immediate) {
      const callNow = !timeout;
      timeout = setTimeout(() => {
        timeout = null;
      }, wait)
      if (callNow) func.apply(context, args)
    }
    else {
      timeout = setTimeout(() => {
        func.apply(context, args)
      }, wait);
    }
  }
}

节流

所谓节流,就是指连续触发事件但是在 n 秒中只执行一次函数。 节流会稀释函数的执行频率。

节流有两种实现:

  1. 时间戳版本
  2. 定时器版本

节流应用场景

  1. scroll 事件,每隔一秒计算一次位置信息等
  2. 浏览器播放事件,每个一秒计算一次进度信息等
  3. input 输入框在搜索内容时,可以控制多少s 在执行请求,避免多次发起请求,节约性能。

时间戳版本

function throttle(func, wait) {
    var previous = 0;
    return function() {
        let now = Date.now();
        let context = this;
        let args = arguments;
        if (now - previous > wait) {
            func.apply(context, args);
            previous = now;
        }
    }
}

定时器版本

function throttle(func, wait) {
    let timeout;
    return function() {
        let context = this;
        let args = arguments;
        if (!timeout) {
            timeout = setTimeout(() => {
                timeout = null;
                func.apply(context, args)
            }, wait)
        }

    }
}

代码解析

当执行 throttle 函数时,timeout 默认为undefined , 此时,! timeouttrue 时,执行 定时器,并且 将 timeout 为 null,即为false, 再次执行throttle 函数时,!timeout 又为 true ,再次执行定时器。

*通过 timeout 的状态来达到节流的控制 *

总结

  • 防抖: 触发事件后,一定时间后再执行事件,可以立即执行 也可以一定时间再执行

  • 节流: 控制流量,在单位时间内只能请求一次,避免多次触发事件,影响服务器性能。

结语

❤️关注+点赞+收藏+评论+转发❤️,原创不易,鼓励笔者创作更好的文章

关注公众号 前端自学社区,即可获取更多前端高质量文章!

关注后回复关键词“加群”, 即可加入 “前端自学交流群”,共同学习进步。

关注后添加我微信拉你进技术交流群

欢迎关注公众号,更多精彩文章只在公众号推送

参考

https://github.com/mqyqingfeng/Blog/issues/26

点赞
收藏
评论区
推荐文章
记录 30 seconds of code 项目个人觉得中有价值的片段或者小技巧(二)
DF系列1、防抖函数,限制高频触发jsconstdebounce(fn,ms0)lettimeoutId;returnfunction(...args)clearTimeout(timeoutId);timeoutIdsetTimeout(()fn.apply(this,args),ms);
落落落洛克 落落落洛克
3年前
性能优化之防抖和节流
我的前端学习笔记📒最近花了点时间把笔记整理到语雀上了,方便童鞋们阅读我的前端学习笔记📒(https://www.yuque.com/wanggangfeng
Chase620 Chase620
3年前
防抖和节流
防抖触发高频事件后n秒内函数只会执行一次,如果n秒内高频事件再次触发,则重新计算事件思路每次触发的时候取消之前的延时调用方法,以当下为准//防抖functiondebounce(fn){lettimeoutnull;returnfunction(){clearTimeout
LinMeng LinMeng
3年前
js的防抖与节流
在进行窗口的resize、scroll,输入框内容校验等操作时,如果事件处理函数调用的频率无限制,会加重浏览器的负担,导致用户体验非常糟糕。此时我们可以采用debounce(防抖)和throttle(节流)的方式来减少调用频率,同时又不影响实际效果。函数防抖函数防抖(debounce):当持续触发事件时,一定时间段内没有再触发事件,事件处理函数才
可莉 可莉
3年前
2020年前端开发面试必考:什么是前端防抖?
防抖(去抖),以及节流(分流)在日常开发中可能用的不多,但在特定场景,却十分有用。!(https://oscimg.oschina.net/oscnet/dc9ed2e656be427d8f3324e57538aa13.png)最近有同学遇到了要做防抖的需求,那今天李老师就来讲解一下,什么是防抖。为了方便查阅和让不了解防抖
Stella981 Stella981
3年前
2020年前端开发面试必考:什么是前端防抖?
防抖(去抖),以及节流(分流)在日常开发中可能用的不多,但在特定场景,却十分有用。!(https://oscimg.oschina.net/oscnet/dc9ed2e656be427d8f3324e57538aa13.png)最近有同学遇到了要做防抖的需求,那今天李老师就来讲解一下,什么是防抖。为了方便查阅和让不了解防抖
如何做好抖音直播带货?
抖音软件现在有多火爆,大家都是有目共睹的,在抖音平台上面有直播的功能,越来越多的抖音用户开始利用抖音直播的功能去带货做推广了,作为一个新手,大家知道如何去做好吗?场控:1.确定直播流程,熟悉产品流程上,包括什么时候抽奖、什么时候分享主题等,都需要提前熟悉。产品上,不仅要熟悉推广商品的性能、参数等,更要实际测评,看看是否真的如同商家所言,避免“翻车”事件。2.
菜园前端 菜园前端
1年前
什么是防抖和节流?
原文链接::::tip防抖和节流一般在做用户体验优化的时候会用上。:::什么是防抖?是指一个事件在同一时间内被多次频繁触发后,最终只会执行一次。多次触发后会重新计算时间,只生效最后一次触发。基础案例可通过定时器来实现javascriptvartimer0f
sum墨 sum墨
1个月前
《优化接口设计的思路》系列:第六篇—接口防抖(防重复提交)的一些方式
所谓防抖,一是防用户手抖,二是防网络抖动。在Web系统中,表单提交是一个非常常见的功能,如果不加控制,容易因为用户的误操作或网络延迟导致同一请求被发送多次,进而生成重复的数据记录。要针对用户的误操作,前端通常会实现按钮的loading状态,阻止用户进行多次点击。而对于网络波动造成的请求重发问题,仅靠前端是不行的。为此,后端也应实施相应的防抖逻辑,确保在网络波动的情况下不会接收并处理同一请求多次。
sum墨 sum墨
1个月前
《优化接口设计的思路》系列:第七篇—接口限流策略
好像一提到防抖,接下来就会提到限流,我在第六篇文章写了一些接口防抖的策略,那么这篇正好讲讲接口如何限流。不知道从哪里看到的,“防抖是回城,限流是攻击”,感觉真的很形象,我来简要描述一下
海军
海军
Lv1
海军,专注Web前端领域开发,分享开发经验与最新前端技术。 微信公众号: 前端自学社区
文章
27
粉丝
11
获赞
33