防抖(debounce)和节流(throttle)的原理以及实现

559 阅读2分钟

在平时开发的过程中,会有很多时候频繁的触发事件,比如说搜索框的实时发送请求,在登录的时候连续点击登录按钮,持续点击轮播图进行图片的更改,当我们不想频繁触发时该怎么办?

一.节流函数和防抖函数概念性的问题

1.使用节流防抖函数的目的?

答:当多次执行某一动作,进行函数调用次数的限制,节省资源

2.防抖的概念是什么?

答:在事件触发n秒后执行函数,如果在n秒内再次触发,重新计时

3.节流的概念是什么?

答:当多次执行某一动作,每隔一段时间,只执行一次函数

4.节流函数和防抖函数的区别是什么?

答:函数节流不管事件触发的有多频繁,都会保证在规定时间内一定会执行一次真正的事件处理函数,而函数防抖只是在最后一次事件后才触发一次函数

二.节流函数和防抖函数的应用场景

一.防抖函数(debounce)应用场景有哪些?

  1. 登录,发短信等按钮避免用户点击太快,以至于发送了多次请求
  2. 搜素框搜索输入,只需要用户最后一次输入完在发送请求
  3. 手机号,邮箱验证输入检测(input,blur,change,keyup)等事件触发,每次都会触发
  4. 窗口大小resize,只需要窗口调整完大小,计算窗口大小,防止重复渲染
  5. 导航条上用户不停的在导航区域滑动
  6. 鼠标的mousemove,mouseover

二.节流函数(throttle)应用场景有哪些?

  1. 多次点击提交,表单重复提交
  2. 滚动加载,加载更多或者滚到底部监听,window.onscroll和滑到底部自动加载更多

三.节流函数和防抖函数是如何实现的?

1.防抖函数

//封装防抖
//新建一个debounce.js文件(一般vue3+ts,也可以用ts)
//新建文件后将以下代码放入
const debounce = (fn, delay) => {
    let timer = null;
    return function () {
        let context = this;
        let args = arguments;
        clearTimeout(timer);
        timer = setTimeout(function () {
            fn.apply(context, args);
        }, delay);
    };
};
export default debounce;


2.节流函数

//封装节流
//新建一个throttle.js文件(一般vue3+ts,也可以用ts)
//新建文件后将以下代码放入
const throttle = (fn, delay) => {
    let valid = true;
    return function () {
        let context = this;
        let args = arguments;
        if (!valid) {
            return false;
        }
        valid = false;
        setTimeout(() => {
            //console.log('coming');
            //fn();
            fn.apply(context, args);
            valid = true;
        }, delay);
    };
};
export default throttle;

注意以上是两个文件,嫌麻烦可以放在同一个文件里,不过格式改为

export const debounce = (fn, delay) =>{...}
export const throttle = (fn, delay) =>{...}
//然后把export default都去掉