本文深入解析JavaScript中防抖(debounce)与节流(throttle)的核心原理,通过手写代码展示其实现逻辑,并对比两者在搜索、滚动等场景下的应用差异。同时提供Lodash库中对应函数的安装与使用指南,帮助开发者优化高频事件处理,提升Web应用性能。
什么是防抖和节流?
在 JavaScript 开发中,防抖(debounce)和节流(throttle)是两种用于控制函数执行频率的关键技术。
防抖(debounce)的核心机制是:在指定的时间间隔内,仅执行最后一次触发的函数调用。若在该时间窗口内再次触发,计时器将重置,直至等待时间结束且无新触发,函数才会执行。该技术常用于处理窗口大小调整、搜索框输入等高频事件,旨在减少不必要的函数调用,从而降低网络开销并提升性能。
节流(throttle)的机制是:在设定的时间间隔内,限制函数的执行频率,确保每隔一段时间仅执行一次调用。无论触发频率多高,函数都会按照指定的时间间隔规律执行。它通常用于处理滚动、鼠标移动等连续触发的事件,通过控制执行频率来减少资源消耗,优化页面性能。
手写一个防抖的工具函数
function debounce(func, delay) {
let timeoutId;
return function() {
const context = this;
const args = arguments;
clearTimeout(timeoutId);
timeoutId = setTimeout(function() {
func.apply(context, args);
}, delay);
};
}函数说明
- 该防抖函数接收两个参数:
func代表需要被防抖处理的原始函数,delay代表延迟执行的时间间隔(单位为毫秒)。 - 函数内部利用
timeoutId变量存储定时器的标识符。当调用防抖函数返回的新函数时,会先清除之前存在的定时器,并创建一个新的定时器。只有当在设定的延迟时间内没有再次调用该新函数时,才会触发原始函数的最终执行。
使用示例
此示例展示了在全局滚动事件中应用防抖函数。在200毫秒的时间窗口内,若持续触发滚动事件,handleScroll()函数不会执行。系统会不断重置200毫秒的计时器,直到最后一个200毫秒周期内未再触发滚动事件,此时才会执行handleScroll()函数。
function handleScroll() {
console.log('Scrolled');
}
const debouncedScroll = debounce(handleScroll, 200);
window.addEventListener('scroll', debouncedScroll);手写一个节流的工具函数
function throttle(func, delay) {
let timeoutId;
let lastExecTime = 0;
return function(...args) {
const currentTime = Date.now();
const remainingTime = delay - (currentTime - lastExecTime);
clearTimeout(timeoutId);
if (remainingTime <= 0) {
func.apply(this, args);
lastExecTime = currentTime;
} else {
timeoutId = setTimeout(() => {
func.apply(this, args);
lastExecTime = Date.now();
}, remainingTime);
}
};
}函数说明
- 该节流函数接收两个参数:
func代表要执行的原始函数,delay代表延迟时间(单位为毫秒)。 - 它返回一个新的函数,该函数在调用时,会根据指定的延迟时间来限制原始函数的执行频率。
使用示例
在全局滚动事件中使用节流函数。无论滚动监听过程中触发handleScroll()函数的次数多少,handleScroll()函数都保证每200毫秒内仅执行一次。
function handleScroll() {
console.log('Scrolled');
}
const throttledScroll = throttle(handleScroll, 200);
window.addEventListener('scroll', throttledScroll);如何在工作中应用防抖和节流
防抖和节流主要应用于:搜索框输入事件监听、窗口大小调整事件监听、按钮点击事件监听、滚动事件监听、鼠标移动事件监听等等场景。
工作中哪些场景可以使用防抖函数?
- 用户输入: 当用户在表单输入框中频繁输入时,可以使用防抖函数来延迟处理用户输入,避免频繁的请求或操作,提高性能和用户体验。
- 搜索框: 在搜索框中,当用户连续输入关键字时,可以使用防抖函数来延迟发送搜索请求,以避免请求过多。
- 窗口调整: 当窗口大小调整时,会触发resize事件,可以使用防抖函数来限制resize事件的触发次数,避免频繁执行调整相关的代码。
- 按钮频繁点击: 当按钮被频繁点击时,可以使用防抖函数来限制按钮点击的触发次数。
工作中哪些场景可以使用节流函数?
- 用户输入: 当用户在文本框中输入时,触发搜索功能。使用节流函数可以限制搜索请求的频率,以避免频繁的网络请求。例如,可以设置一个定时器,在用户输入后的一小段时间内不触发搜索请求,只在定时器结束后才进行搜索。
- 无限加载: 当用户滚动页面时,触发加载更多数据的操作。使用节流函数可以限制加载操作的频率,以提高页面的响应性能。例如,可以设置一个定时器,在用户滚动过程中只触发加载操作的最后一次滚动事件。
- 按钮频繁点击: 当用户频繁点击某个按钮时,触发某个操作。使用节流函数可以限制点击操作的频率,以避免重复操作或者混乱的界面状态。例如,可以设置一个定时器,在用户点击后的一小段时间内不触发重复操作。
如何使用loadsh.js工具库中的防抖和节流函数
实际开发过程中,我们的项目中可能会直接使用loadsh.js工具库,来避免重复造轮子,所以这里也特地说明一下如何使用loadsh.js工具库中的防抖和节流函数
- 安装
loadsh.js工具库
npm install lodash - 在项目中引入
loadsh.js工具库,不同前端项目引入方式不同,请自行鉴别
import { debounce, throttle } from 'loadsh';- 使用防抖函数,该示例中,
submitData()函数被限制为每1秒只会执行最后一次,如果在等待时间内多次调用该函数,则会重置1秒的等待时间
// 定义要延迟执行的函数
function submitData(data) {
console.log('保存数据:', data);
}
// 使用debounce函数创建一个延迟执行的函数
const debouncedFn = _.debounce(submitData, 1000);
// 模拟连续触发保存数据的操作
// 等待1秒后,只会执行最后一次保存数据的操作
debouncedFn('数据1'); // 不会输出
debouncedFn('数据2'); // 不会输出
debouncedFn('数据3'); // 输出 —— 保存数据:数据3- 使用节流函数,该示例中,
throttledFn()函数被限制为每秒只能执行一次,如果在等待时间内多次调用该函数,则不会执行
// 定义要减少调用次数的函数
function fetchData(data) {
console.log('拉取数据:', data);
}
// 使用throttle函数创建一个定时执行的函数
const throttledFn = _.throttle(fetchData, 2000);
// 调用throttledFn函数
throttledFn('数据1'); // 输出 —— 拉取数据: 数据1
// 在1秒内多次调用throttledFn函数
throttledFn('数据2'); // 不会输出
// 2秒后再次调用throttledFn函数
setTimeout(() => {
throttledFn('数据3'); // 输出 —— 拉取数据: 数据3
}, 1000);以上就是浅谈JavaScript中的防抖和节流的详细内容,更多关于JavaScript防抖节流的资料请关注本站其它相关文章!