JS-函数防抖与节流学习

4e56aed8047b18489beb757ccf626813.jpg

  • 前言

函数防抖与节流在许多大厂(比如阿里、字节)面试题中经常有出现,跟随大厂的脚步,在此做一个记录学习备用

  • 正文

  • 防抖(debounce)

字面意思,防止抖动嘛~ 不要让ta随意乱抖,太夸张的动作,物极必反,影响性能。
定义: 任务频繁触发的情况下,只有任务触发的间隔超过指定间隔的时候,任务才会执行。就是在事件被触发n秒后再执行回调,如果在这n秒内又被触发,则重新计时。

举个🌰 : 比如一个input 搜索框的模糊搜索,每次输入完要请求一次接口,这无疑会对服务器造成压力,所以这里防抖就可以设置比如在2秒内如果没有重新继续输入的话,就请求一次接口,而不是一输完立马发起请求。

  • 节流(throttle)

字面意思,节约流量? 过分的请求操作,肯定对服务器有压力,流量损耗,所以要操作节约流量,故名节流咯?

定义:指定时间间隔内只会执行一次任务。就是规定一个单位时间,在这个单位时间内,只能有一次触发事件的回调函数执行,如果在同一个单位时间内某事件被触发多次,只有一次能生效。

举个🌰 : 比如一个页面很长,而现在需要监听滚动事件判断是否到页面底部自动加载更多,那如果单纯用防抖,就会一直在等待到停止滚动才有回去加载更多,那用户就需要在最后停止滚动的时候进行等待,体验不是很好,这时候如果如果是 throttle 的话,只要页面滚动就会间隔一段时间判断一次,体验会更好

  • 实现

  1. 函数防抖(debounce)
    以高程三中的防抖为例
// 在窗口内滚动一次,停止,1000ms 后,打印了 hello world,因为我们设置了一个 1000ms 延迟的定时器,如果在 1000ms内不停止的不断滚动,则一直不会触发
function throttle(method, context) { // 高程三这里显然是命名错了,这应该是防抖才对 debounce,网上也有很多在纠正这个错误的
  clearTimeout(method.tId);
  method.tId = setTimeout(function() {
    method.call(context);
  }, 1000);
}

function print() {
  console.log('hello world');
}

window.onscroll = function() {
  throttle(print);
};
我的使用场景是防止用户多次点击提交去请求接口,针对我的应用场景我的点击方法还有需要传参改写如下
const debounce = (fn, delay) => {
  let timer = null;
  return () => {
    if (timer) clearTimeout(timer);
    timer = setTimeout(() => {
      fn.apply(this, arguments);  // 也可用 fn.call(this, ...arguments) 这里关于apply 与 call还有一个bind的区别,请关注下篇文章
    }, delay);
  }
}
  1. 函数节流(throttle)
const throttle = (fn, delay) => {
  let last = 0;
  return function () {
    if (Date.now() - last > delay) {
      last = Date.now()
      setTimeout(() => {
        fn.apply(this, arguments);
      }, delay);
    }
  }
}
  • 相同点与不同点

    相同点
    函数节流(throttle)与 函数防抖(debounce)核心都是为了限制函数的执行频次,以达到优化函数触发频率过高导致的响应速度跟不上触发频率,出现延迟,假死或卡顿现象的目标。
    不同点
    函数防抖(debounce)是触发n秒后再执行回调,如果n秒内一直被触发,则会一直再等n秒才会执行回调。
    函数节流(throttle)是无论你触发多少次,都会固定n秒去请求一次,如果不触发则不请求 防抖和节流的区别在于以第一次为准还是最后一次为准。
  • 其他使用场景举例

debounce 应用场景 (哪些时候对于连续的事件响应我们只需要执行一次回调?)
  • 每次 resize/scroll 触发统计事件
  • 文本输入的验证(连续输入文字后发送 AJAX 请求,只在用户停止键入时发送)
throttle 应用场景 (哪些时候我们需要间隔一定时间触发回调来控制函数调用频率?)
  • DOM 元素的拖拽功能实现(mousemove)
  • 计算鼠标移动的距离(mousemove)
  • 监听滚动事件判断是否到页面底部自动加载更多:给 scroll 加了 debounce 后,只有用户停止滚动后,才会判断是否到了页面底部;如果是 throttle 的话,只要页面滚动就会间隔一段时间判断一次
  • 小结

函数节流和函数去抖的核心其实就是限制方法被频繁触发,大多数情况下因为 DOM 事件的监听回调,所以方法会被频繁触发,因此才出现了防抖(debounce)和节流(throttle)。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值