面试-搬砖到城堡1:JS防抖和节流及应用场景

概述

严格来说,防抖和节流其实算是性能优化的问题,因为日常开发场景中使用场景偏多,有些场景如果不使用会有很大的开销问题甚至卡死。所以会在一些面试中被用来作为面试的考点之一。

简单来说,就是使用函数将多次的计算(监听、操作)合并成一个,并在可控的精确点进行操作。

防抖和节流都是为了解决短时间内大量触发某函数而导致的性能问题

1、防抖函数(debounce)

1.1 函数效果

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

1.2 应用场景

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

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

1.3 函数实现

思路:

每次触发事件时设置一个延迟调用方法,并且取消之前的延时调用方法

代码展示:

function Debounce(fn, delay) {
    let timer = null;
    return function() {
        // 每当你在delay的时间范围内触发了函数,会清空上一个timer,重新走新的timer,定时器的时间会进行刷新
        if(timer) {
            clearTimeout(timer)
        }
        timer = setTimeout(()=> {
            fn.apply(this, arguments)
        }, delay)
    }
}

// 简单实例
function ajax(content) {
    console.log('ajax request ' + content)
}

let myInput = document.getElementById('debounce')
let deAjax = Debounce(ajax, 500)
myInput.addEventListener('keyup', function (e) {
    deAjax(e.target.value)
})
复制代码

2、节流函数(throttle)

2.1 函数效果

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

2.2 应用场景

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

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

(3)监听滚动事件,比如是否滑到底部自动加载更多,用throttle来判断;

2.3 函数实现

思路:

每次触发事件时,如果当前有等待执行的延时函数,则直接return

代码展示:

function Throttle(fn, delay) {
    let isRun = true // 第一次进来时触发
    return function() {
        // 如果在规定时间内触发过,则return不往后继续执行
        if(!isRun) {
            return false
        }
        isRun = false;
        setTimeout(() => {
            fn.apply(this, arguments);
            // 执行完毕后,修改回初始值,以便下次使用
            isRun = true;
        }, delay)
    }
}

// 简单实例
function ajax(content) {
    console.log('ajax request ' + content)
}

let myInput = document.getElementById('throttle')
let thAjax = Throttle(ajax, 1000)
myInput.addEventListener('click', function (e) {
    thAjax(e.target.value)
})
复制代码
© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享