前端面试题--防抖和节流

164 阅读2分钟

今天面试第一个的问题就是说一下防抖和节流,所以下来整理一下防抖和节流的答案。从区别、应用场景、实现原理三个方面来说明。

1. 节流

1.1 概念

就是指连续触发事件但是在设定的一段时间内只执行一次函数。例如:设定1000毫秒执行,那你在1000毫秒内触发多次,也只在1000毫秒后执行一次。就像公交车一样,不是来一个乘客就发一趟车,而是十分钟发一趟车。

单位时间内,频繁触发,只执行一次

1.2 场景

高频事件:快速点击、鼠标滑动、resize事件、scroll事件

1.3 代码实现思路

利用定时器,等定时器执行完毕,才开始定时器

//下拉加载更多
window.onscroll = throttle(function () {
    console.log("加载了一页!!!");
},1000)
​
function throttle(fn, delay) {
    let timer = true;
    return function () {
        if (timer) {
            setTimeout(() => {
                fn.call(this)
                timer = true;
            }, delay);
        }
        timer = false;
    }
}

2. 防抖

2.1 概念

就是指连续触发事件但是在设定的一段时间内只执行最后一次,例如设定1000毫秒执行,当你触发事件了,他会在1000毫秒后执行,但是在还剩500毫秒的时候你又触发了事件,那就会重新开始1000毫秒之后再执行。好像手机一直玩就不息屏,隔一分钟不玩了就息屏。

单位时间内,频繁触发事件,只执行最后一次

2.2 场景

搜索框搜索输入、文本编辑器实时保存

2.3 代码实现思路

利用定时器,每次触发先清掉以前的定时器。

//搜索案例
//<input type="text" id="search">
let search = document.getElementById("search");
let timer = null;
search.oninput = function () {
    // 清除前面的定时器
    if (timer !== null) {
        clearTimeout(timer)
    }
    // 保留最后一次定时器
    timer = setTimeout(() => {
        console.log(this.value);
    }, 1000);
}
//使用闭包,优化代码
let search = document.getElementById("search");
​
search.oninput = debounce(function(){
    console.log(this.value);
},1000)
​
function debounce(fn,delay) {
    let timer = null;
    return function () {
        // 清除前面的定时器
        if (timer !== null) {
            clearTimeout(timer)
        }
        // 保留最后一次定时器
        timer = setTimeout(() => {
            fn.call(this)
        }, delay);
    }
}

3. lodash库

开发中一般使用lodash库,利用里面的防抖(debounce)和节流(throttle)。

// 防抖:单位时间,频繁出发,执行最后一次
search.oninput = _.debounce(function () {
    console.log(this.value);
}, 1000)
​
// 节流:单位时间,频繁出发,只执行一次
window.onscroll = _.throttle(function () {
    console.log("加载下一页!!");
}, 1000, {
    trailing: true,
    leading: false
})