防抖和节流如何更好的理解

本质都是为了防止函数高频调用,利用闭包特性来缓存变量(状态)。

1、防抖(debounce)重在清零 clearTimeout(timer),执行最后一次

原理:调用函数fn在一段时间后才执行,如果这段时间再次调用,则重新计算执行时间,如果规定的时间没有再次调用该函数,则执行函数fn

function debounce(fn, wait) {
    let timer = null;
    return function () {
        let _this = this;
        let _arg = arguments;
        if (timer) {
            clearTimeout(timer);
            timer = null;
        }
        timer = setTimeout(function () {
            fn.apply(_this, _arg);
        }, wait);
    }
}

如果需要第一次立即执行,可以加个immediate参数,表示是否立即执行,函数里加个count计数,如果是第一次并且immediate 为ture时立即执行。 

function debounce(fn, wait, immediate) {
    immediate = immediate || false;
    let timer = null;
    let count = 0;
    return function () {
        let _this = this;
        let _arg = arguments;
        clearTimeout(timer);
        if (immediate && !count) {
            fn.apply(_this, _arg);
            count++;
        } else {
            timer = setTimeout(function () {
                fn.apply(_this, _arg);
                count++;
            }, wait);
        }
    }
}

需要注意的点就是this指向问题和函数参数如何获取

应用场景:1、按钮提交事件  2、scroll事件滚动触发 3、表单元素实时校验 4、用户编辑实时保存 5.调整浏览器窗口resize

 

2、节流(throttle)重在 开锁关锁 timer=timeout; timer=null,间隔执行

原理: 单位时间内,只能触发一次fn函数。如果这个单位时间内触发多次函数,只有一次生效。 

1、通过定时器实现。只会在time时间内触发一次。

function throttle(fn, time) {
    let timer = null;
    return function() {
        let _this = this;
        let args = arguments;
        if(!timer) {
            timer = setTimeout(() => {
                timer = null;
                fn.call(_this, args);
            }, time)
        }
    }
}

2、通过时间戳实现。可以在立即执行一次,之后在time时间内只触发一次fn函数。

function throttle(fn, time) {
    let initialTime = 0;
    return function() {
        let _this = this;
        let args = arguments;
        let currrentTime = new Date().getTime();
        if(currrentTime - initialTime > time){
            initialTime = currrentTime;
            fn.apply(_this, args);
        }
    }
}

应用场景:1、input实时搜索请求接口 2、dom元素拖拽 3、射击游戏(鼠标) 4、计算鼠标移动距离 5、监听滚动条事件,是否滑动到底部加载更多 6、跟随鼠标一些动画

 

你可能感兴趣的:(javascript,javascript)