什么是节流和防抖,如何实现?应用场景

一、是什么

        二者本质上都是优化高频率执行代码的一种手段

        1.节流(throttle):

          定义:n 秒内只运行一次,若在 n 秒内重复触发,只有一次生效。

                     

        2.防抖(debounce):

         定义:n 秒后在执行该事件,若在 n 秒内被重复触发,则重新计时。

二、实现

        1.节流:

        在第一次触发事件的时候开启一个定时器,如果在定时器期间重复触发该事件,则不做任何操作。等定时器结束后执行事件。

使用定时器实现:

function throttled(fn, delay = 500) {
    let timer = null
    return function (...args) {
        if (!timer) {
            timer = setTimeout(() => {
                fn.apply(this, args)
                timer = null
            }, delay);
        }
    }
}

 也可以选择立即执行函数,然后n秒内不在执行

function throttled(fn, delay = 500) {
    let timer = null
    return function (...args) {
        if (!timer) {
            //立即执行
            fn.apply(this, args)
            timer = setTimeout(() => {
                timer = null
            }, delay);
        }
    }
}

 或者使用这个:

function debounce(fn, delay = 500,immediate = true) {
  let timer = null;
  return function (...args) {
    if (timer) {
      clearTimeout(timer)
      timer = setTimeout(() => {
        fn.apply(this, args);
        timer = null; 
      },delay)
    }
    else {
      fn.apply(this, args);
      timer = setTimeout(() => {
        timer = null;
      }, delay);
    }
  };
}

 2.防抖:    

    触发事件后开启定时器,期间再次触发则清除当前定时器,重新开启,直至最后一次的定时器结束,执行事件。

function debounce(fn, delay) {
    let timeout;

    return function () {
        let context = this; // 保存this指向
        let args = arguments; // 拿到event对象

        clearTimeout(timeout)
        timeout = setTimeout(function(){
            fn.apply(context, args)
        }, delay);
    }
}

 想要立即执行:

function debounce(fn, delay, immediate) {

    let timeout;

    return function () {
        let context = this;
        let args = arguments;

        if (timeout) clearTimeout(timeout); // timeout 不为null
        if (immediate) {
            let callNow = !timeout;//第一次timeout为undefin
            if (callNow) {
                fn.apply(context, args)
            }
            timeout = setTimeout(function () {
                //用于最后一次触发函数
                if(!callNow) {
                   fn.apply(context, args)
                }
                timeout = null;
            }, delay)
        }
        else {
            timeout = setTimeout(function () {
                fn.apply(context, args)
            }, delay);
        }
    }
}

三、应用场景

节流在间隔一段时间执行一次回调的场景有:

  • 滚动加载,加载更多或滚到底部监听
  • 搜索框,搜索联想功能
  • 发送短信验证码
  • 其他需要n秒后再操作的场景

防抖在连续的事件,只需触发一次回调的场景有:

  • 搜索框搜索输入。只需用户最后一次输入完,再发送请求
  • 手机号、邮箱验证输入检测
  • 窗口大小resize。只需窗口调整完成后,计算窗口大小。防止重复渲染。


                

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值