防抖与节流以及区别

防抖函数的作用是什么?请实现一个防抖函数

防抖函数的作用

防抖函数的作用就是控制函数在一定时间内的执行次数。防抖意味着N秒内函数只会被执行一次,如果N秒内再次被触发,则重新计算延迟时间。

举例说明: 小思最近在减肥,但是她非常吃吃零食。为此,与其男朋友约定好,如果10天不吃零食,就可以购买一个包(不要问为什么是包,因为包治百病)。但是如果中间吃了一次零食,那么就要重新计算时间,直到小思坚持10天没有吃零食,才能购买一个包。所以,管不住嘴的小思,没有机会买包(悲伤的故事)... 这就是 防抖。

防抖函数实现

事件第一次触发时,timer 是 null,调用 later(),若 immediate 为true,那么立即调用 func.apply(this, params);如果 immediate 为 false,那么过 wait 之后,调用 func.apply(this, params)

事件第二次触发时,如果 timer 已经重置为 null(即 setTimeout 的倒计时结束),那么流程与第一次触发时一样,若 timer 不为 null(即 setTimeout 的倒计时未结束),那么清空定时器,重新开始计时。

function debounce(func, wait, immediate = true) {

    let timeout, result;

    // 延迟执行函数

    const later = (context, args) => setTimeout(() => {

        timeout = null;// 倒计时结束

        if (!immediate) {

            //执行回调

            result = func.apply(context, args);

            context = args = null;

        }

    }, wait);

    let debounced = function (...params) {

        if (!timeout) {

            timeout = later(this, params);

            if (immediate) {

                //立即执行

                result = func.apply(this, params);

            }

        } else {

            clearTimeout(timeout);

            //函数在每个等待时延的结束被调用

            timeout = later(this, params);

        }

        return result;

    }

    //提供在外部清空定时器的方法

    debounced.cancel = function () {

        clearTimeout(timer);

        timer = null;

    };

    return debounced;

};

immediate 为 true 时,表示函数在每个等待时延的开始被调用。immediate 为 false 时,表示函数在每个等待时延的结束被调用。

防抖的应用场景

搜索框输入查询,如果用户一直在输入中,没有必要不停地调用去请求服务端接口,等用户停止输入的时候,再调用,设置一个合适的时间间隔,有效减轻服务端压力。

表单验证

按钮提交事件。

浏览器窗口缩放,resize事件(如窗口停止改变大小之后重新计算布局)等。




节流函数的作用是什么?有哪些应用场景,请实现一个节流函数

节流函数的作用

节流函数的作用是规定一个单位时间,在这个单位时间内最多只能触发一次函数执行,如果这个单位时间内多次触发函数,只能有一次生效。

节流函数实现

function throttle(func, wait, options = {}) {

    var timeout, context, args, result;

    var previous = 0;

    var later = function () {

        previous = options.leading === false ? 0 : (Date.now() || new Date().getTime());

        timeout = null;

        result = func.apply(context, args);

        if (!timeout) context = args = null;

    };

    var throttled = function () {

        var now = Date.now() || new Date().getTime();

        if (!previous && options.leading === false) previous = now;

        //remaining 为距离下次执行 func 的时间

        //remaining > wait,表示客户端系统时间被调整过

        var remaining = wait - (now - previous);

        context = this;

        args = arguments;

        //remaining 小于等于0,表示事件触发的间隔时间大于设置的 wait

        if (remaining <= 0 || remaining > wait) {

            if (timeout) {

                //清空定时器

                clearTimeout(timeout);

                timeout = null;

            }

            //重置 previous

            previous = now;

            //执行函数

            result = func.apply(context, args);

            if (!timeout) context = args = null;

        } else if (!timeout && options.trailing !== false) {

            timeout = setTimeout(later, remaining);

        }

        return result;

    };

    throttled.cancel = function () {

        clearTimeout(timeout);

        previous = 0;

        timeout = context = args = null;

    };

    return throttled;

}

禁用第一次首先执行,传递 {leading: false} ;想禁用最后一次执行,传递 {trailing: false}

节流的应用场景

按钮点击事件

拖拽事件

onScoll

计算鼠标移动的距离(mousemove)


防抖与节流区别

防抖:    触发高频事件后 n 秒内函数只会执行一次,如果 n 秒内高频事件再次被触发,则重新计算时间;

思路: 每次触发事件时都取消之前的延时调用方法:


节流:    高频事件触发,但在 n 秒内只会执行一次,所以节流会稀释函数的执行频率。

思路:每次触发事件时都判断当前是否有等待执行的延时函数。

你可能感兴趣的:(防抖与节流以及区别)