js防抖和节流

182 阅读2分钟

一、概念

防抖**(debounce)**:事件被触发n秒后再执行回调函数,如果在这n秒内又被触发,则重新计时。

节流**(throttle)**:规定一个单位时间,在这个单位时间内,只能有一次触发事件的回调函数执行,如果在同一个单位时间内某事件被触发多次,只有一次能生效。

二、作用

函数节流函数防抖都是为了限制函数的执行频次,以优化函数触发频率过高导致的响应速度跟不上触发频率,出现延迟,假死或卡顿的现象。

三、应用场景

防抖:

(1) 用户在输入框中连续输入一串字符后,只会在输入完后去执行最后一次的查询ajax请求,这样可以有效减少请求次数,节约请求资源;

(2) window的resize、scroll事件,不断地调整浏览器的窗口大小、或者滚动时会触发对应事件,防抖让其只触发一次;

// 函数防抖
var timer = false;
document.getElementById("debounce").onscroll = function(){
    clearTimeout(timer); // 清除未执行的代码,重置回初始化状态

    timer = setTimeout(function(){
        console.log("函数防抖");
    }, 300);
};

// 函数节流的要点,需要一个setTimeout来辅助实现。延迟执行需要跑的代码。// 如果方法多次触发,则把上次记录的延迟执行代码用clearTimeout清掉,重新开始。// 如果计时完毕,没有方法进来访问触发,则执行代码。

节流:

(1)鼠标连续不断地触发某事件(如点击事件),在单位时间内只触发一次;

(2)在页面无限加载场景下,需要用户在滚动页面时,每隔一段时间发一次 ajax 请求,而不是在用户停下滚动页面操作时才去请求数据;

(3)监听滚动事件,例如是否滑到底部、自动加载更多;

// 函数节流
var canRun = true;// 保存一个标记
document.getElementById("throttle").onscroll = function(){
    if(!canRun){
        // 判断是否已空闲,如果在执行中,则直接return
        return;
    }

    canRun = false;
    setTimeout(function(){
        console.log("函数节流");
        canRun = true;
    }, 300);
};
// 函数节流的要点是,声明一个变量当标志位,记录当前代码是否在执行。
// 如果代码正在执行,则取消这次方法执行,直接return。
// 最后在setTimeout执行完毕后再把标记设置为true(关键)表示可以执行下一次循环了。

四、区别