防抖(debounce)和节流(throttle) 以及他们的区别

在学习前端或者刷面试题的时候我们总是会听到两个两个令人迷惑的专有名词--防抖、节流,相信大家都被这两个名词困扰过,笔者本人也曾被困扰过,也是翻了很多资料看了很多大牛发的博客也才弄明白了,我用这篇文章来总结什么是防抖?什么是节流?以及他们的区别

防抖(debounce)

概念有助于我们对其理解,我们先来看看防抖的概念吧

概念:防抖是指当持续触发事件时,一定时间段内没有再触发事件,事件处理函数执行一次,如果设定时间到来事件函数执行之前又触发了该事件,就重新开始计时。也就是说当一个用户一直触发这个函数,且每次触发函数的间隔小于既定时间,那么在防抖的情况下只会执行一次。

解释:在防抖的情况下,当用户在短时间内频繁触发一个事件,该事件不会执行很多次,它只会执行一次。

举例:小明想点一杯奶茶,于是跟奶茶前台小姐姐说:“姐姐,来杯珍珠奶茶”,可是这时他突然又想要布丁奶茶,正好珍珠奶茶也还没有做,于是跟前台小姐姐说:“姐姐,算了给我来杯布丁奶茶吧”,这时突然他又想喝红豆奶茶,正好珍珠奶茶也还没有做,于是又跟前台小姐姐说:“姐姐,算了还是来杯红豆奶茶吧”。于是最后小姐姐给小明做了一杯红豆奶茶。

 在这里,小姐姐从点单到去做奶茶的间隔时间就是防抖自定义的时间,点奶茶就是事件触发,小姐姐做奶茶就是执行事件,小明就是用户,小明在间隔时间之内重复触发事件(也就是频繁点奶茶),但是事件只会执行一次(只做一杯奶茶),因为他只想要一杯奶茶。不能因为他频繁点单跟换选择而把他点的全部做出来,这违反了小明的本意,也就是用户的本意,于是就有了‘防抖’。

代码来表示:

//fun为要设置防抖的函数,delay为要设置的延时执行的间隔时间,也就是防抖的间隔时间
function debounce (fun, delay) {
  let timeout=null;
  return function() {
// 如果timeout == null说明是第一次触发事件,直接执行回调函数,否则重新开始计时
timeout == null ? fn.call(this, ...arguments) : clearTimeout(timeout);
    timeout = setTimeout(fn.bind(this), delay, ...arguments);//设置定时器
  }
}

代码看起来十分的简单,但是理解起来却不容易,这里涉及到了闭包的概念,要是还不明白闭包是什么建议先去看看闭包,理解了闭包再看这段代码其实也是so easy啦

节流(throttle)

概念:节流是指动作绑定事件后,动作触发事件,在这段时间内,如果动作又发生,则无视该动作,直到事件执行完后,才能重新触发

解释:听完概念是不是觉得和防抖很像很像,觉得几乎完全一样?其实它们还是有很大的区别的,

具体请看后文防抖和节流的区别。节流是在节流自定义的间隔时间内再次触发一次或多次该事件,除了第一次触发,其余触发都将无视掉,就相当于期间什么也没发生,当然这是指第一次触发的事件到该执行之前,在执行结束后再次触发将重新计算,也就是重新来一遍,要是在这次事件执行之前再次或多次触发将被无视。

举例:你向老师提问,老师转过头在黑板上写字,写两分钟,在这两分钟内老师都不会回头看你们,在这期间你做什么老师都不会管你,就算你还向老师提问老师也不会搭理你,在这期间你被无视,直到两分钟到了老师回头看着你,如果你又向老师提了一个问题,他将又转头写字两分钟

这里两分钟就是节流间隔时间(当然这间隔时间是很长的,这是为了方便理解才把间隔时间说长的,实际节流的间隔时间都是非常短的) 老师写完字就是事件执行结束,而提问就是触发事件。

代码来表示:

//fun为要设置节流的函数,delay为节流的间隔时间
function throttle (fn, delay) {
  let timeout=null;
  let start = new Date();//记录开始时间
  return function () {
    const current = new Date() - 0;// 触发时间
    timeout && clearTimeout(timeout);
    // 如果到了时间间隔点(也就是事件刚刚执行结束的时间点),就执行一次回调
    if (current - start >= delay) {
      fn.call(this, ...arguments);
      start = current;// 重置开始时间
    } else {
      // 保证函数在脱离事件以后还会执行一次
      timeout = setTimeout(fn.bind(this), threshhold, ...arguments);
    }
  }
}

防抖和节流的区别

防抖是在已经触发事件但事件的回调函数还没执行期间再次触发事件,会重置定时器记录的时间,也就是重新计算delay时间后再执行回调,期间再次触发同理。主要用于input.change实时输入校验、window.resize浏览器窗口缩放等。

节流是始终以第一次事件触发为起点,忽略节流时间内的所有事件,第一次事件的回调执行完之后再触发第二次事件。函数节流用在比input更频繁触发的事件中其中大部分是涉及动画的操作,如touchmove, mousemove, scroll,throttle... 

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

码上十七

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

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

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

打赏作者

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

抵扣说明:

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

余额充值