防抖和节流
前言
- 作为前端开发中会以下两种需求
- 搜索需求
搜索的逻辑就是
监听用户输入事件,等用户输入完成之后把数据发送给后端,后端返回匹配数据,前端显示数据到页面。
如果只要用户输入就发请求,这样会给后端造成请求压力,需要控制请求的频率。- 页面无限加载数据
页面无限加载数据的逻辑就是
监听用户用户滚动事件,在用户滚动的过程中,去请求下一页的数据来显示到页面。
,那么只要滚动就去发请求,同样会造成后端请求压力,需要控制请求的频率。 - 以上两种看起来都是控制请求频率的问题,但是需求有细微的差别:
搜索是用户在输入中输入多次,只有等用户短暂停止输入之后,就去发送请求,此时就需要防抖去实现。滚动加载数据是在用户滚动页面的过程中每间隔一段时间就去请求,即使用户一直滚动,都会去请求,而不是等用户停止滚动才去请求,此时就需要使用节流去实现。
防抖
- 含义
简单的理解方式就是:用户多次触发事件,在用户一直触发事件中,事件不会执行,只有在用户停止触发事件一段时间之后再执行这个事件一次。
- 实现
// @fn 是对应请求数据
// @ms 是用户多次触发事件的时间间隔 是一个毫秒数
function debounce(fn, ms) {
let timeout = null
return function() {
clearTimeout(timeout)
timeout = setTimeout(() => {
fn.apply(this, arguments)
}, ms)
}
}
- 原理
用户每一次触发事件都会延迟执行,在设置延迟定时器执之前都会把上一次延迟定时器清除,最终只有用户连续触发这个事件的间隔时间超出我们设置的参数ms毫秒之后,该事件才会触发一次
- 测试
<input id="searchInput"/>
function getData(){
console.log('发送请求...')
}
document.getElementById('searchInput').oninput = debounce(getData, 800)
// 如果用户一直在输入,是不会发送请求
// 只有用户连续输入时间间隔超过800ms之后才会请求一次数据,也就是用户在800ms内没有输入才会去请求数据
节流
- 含义
简单的理解方式就是:用户多次触发事件,在用户一直触发事件过程中事件会每间隔一段时间执行一次,会执行多次。
- 实现
// @fn 是对应请求数据
// @ms 是用户多次触发事件的时间间隔 是一个毫秒数
function throttle(fn, ms){
let flag = true
return function(){
if(!flag) return
flag = false
setTimeout(()=>{
fn.apply(this, arguments)
flag = true
}, ms)
}
}
- 原理
用户每一次触发事件都会设置一个延迟定时器,但是如果已经设置了延迟定时器就会等上一次延迟定时器执行之后才会开启下一个定时器,这样用户一直触发事件,事件会每间隔一段时间执行一次
- 测试
function getData(){
console.log('发送请求...')
}
window.onscroll = throttle(getData, 800)
// 用户在滚动的过程中,会间隔去请求数据
总结
节流和防抖本质上都是控制事件执行的频率,但是触发事件的时机本质上有区别,防抖是在用户多次触发事件,当用户停止触发事件,将事件执行一次;节流是用户多次触发事件,会在多次触发的过程中,间隔执行事件。