函数节流

67 阅读2分钟

什么是函数节流?

概念:限定一个函数在一定时间内只能执行一次,执行的是第一次

为什么需要函数节流(防抖)?

前端开发过程中,有一些事件/函数会被频繁地触发,例如onresize、scroll、mousehover等鼠标事件,这些事件的触发频率很高,不做限制的话,每秒内执行几十次甚至更多,会造成计算机资源的浪费.

如果函数内部执行了DOM操作,会降低程序运行速度,容易造成浏览器卡死、崩溃.

如果函数内部执行了ajax,会造成请求数据混乱、网络阻塞、占用服务带宽、增加服务器压力

实现思路

给一个标志,根据这个标志去判断是否执行,执行完取反这个标志

根据两次时间戳的差判断,执行完后更新原始时间戳变量

实现方案

// 定时器方案
function throttle (fn, wait){
    var time = null;
    return function(){
        if(!timer) {
            timer = setTimeout(function(){
                fn.applay(this,arguments);
                timer = null;
            },wait)
        }
    }
}

function test(){
    console.log(Math.random());
}

window.addEventListener("mousehover", throttle(test, 1000));

//时间戳方案
function throttle (fn, wait){
    var pre = Date.now();
    return function(){
    var now = Date.now();
        if(now - pre >= wait) {
            timer = setTimeout(function(){
                fn.applay(this,arguments);
                pre = Date.now();
            },wait)
        }
    }
}

function test(){
    console.log(Math.random());
}

window.addEventListener("mousehover", throttle(test, 1000));

使用场景

1.滚动加载、监听滚动条位置

2.百度搜索框、搜索联想/推荐功能

3.高频点击提交、重复表单提交

扩展补充对比:函数防抖

概念:频繁触发后,会清除掉前一次的执行,限定时间后,执行最后一次触发的防抖函数

思路:通过闭包保存一个标记来保存setTimeout返回的值,每当用户输入的时候把前一个setTimeoutclear 掉,然后又创建一个新的setTimeout,这样就能保证interval间隔内如果还有触发操作的话,就不会执行fn函数了。

实现方案:

function debounce(fn, interval = 300) {
    let timeout = null;
    return function () {
        clearTimeout(timeout);
        timeout = setTimeout(() => {
            fn.apply(this, arguments);
        }, interval);
    };
}