JavaScript 中的函数防抖(Debounce)和函数节流(Throttle)是两种优化频繁触发事件回调函数执行的技术,它们主要用于限制函数调用的频率,尤其是在处理高频率触发且响应开销较大的用户交互场景时。
函数防抖 (Debounce)
防抖函数的主要作用是在连续快速触发事件后,只有当事件停止触发一段时间(通常是最后一次触发后的指定间隔)才会执行一次回调。这种策略确保了在短时间内大量重复触发同一事件的情况下,只会执行一次实际操作。例如,在搜索框输入实时查询的场景下,我们不希望用户每输入一个字符就发送一次请求,而是等用户停止输入一段时间后再发起请求。
简单实现防抖函数的方式是通过设置一个定时器,每次事件触发时清除上一次的定时器,并重新设定一个新的定时器,这样只有最后一次触发事件后的等待期满才真正执行函数。
<style>
.input {
margin: 20px;
}
#result {
height: 150px;
line-height: 150px;
text-align: center;
color: #081ee6e5;
background-color: #cccccc;
font-size: 80px;
}
</style>
<div class="input">文本内容
<input type="text" oninput="handleInput()" id="input">
</div>
<div id="result"></div>
<script>
let inputVal = '';
function handleInput() {
inputVal = document.getElementById("input").value;
// console.log(inputVal)
let resultVal = document.getElementById("result");
resultVal.innerHTML = inputVal;
}
function debounce(cont, wait) {
let timeout = null;
return function () {
if (timeout) {
clearTimeout(timeout);
}
timeout = setTimeout(() => {
cont.apply(this);
}, wait)
}
}
document.getElementById("input").oninput = debounce(handleInput, 1000);
</script>
函数节流 (Throttle)
函数节流则保证在一定时间内只执行一次函数,即使这段时间内事件被多次触发。不同于防抖的是,节流函数会按照固定的时间间隔去执行,而不仅仅关注事件是否还在持续触发。这对于那些需要维持一定频率更新而又不想过于频繁的情况非常有用,比如滚动事件监听、窗口大小改变时重新计算布局等。
简单的节流函数实现可以使用定时器加上标志位来控制函数执行:
<div id="content2">
机器学习是人工智能的一个分支,它主要基于计算机科学,旨在使计算机系统能够自动地从经验和数据中进行学习并改进,
而无需进行明确的编程。机器学习算法通过构建模型来处理和分析大量数据,以便能够识别模式、
进行预测、做出决策或进行其他类型的分析。
</div>
<script>
let num2 = 1;
let content2 = document.getElementById("content2");
function handleView() {
// content2.innerHTML = num2++;
console.log('第' + num2++ + '次触发节流');
}
content2.onmousemove = handleView;
function throttle(cont2, wait) {
let timeout;
return function () {
if (!timeout) {
timeout = setTimeout(() => {
timeout = null;
cont2.apply(this);
}, wait)
}
}
}
content2.onmousemove = throttle(handleView, 1000);
</script>
总结来说,防抖是将多次执行变为最后一次执行,节流是将多次执行变为每隔一段时间执行。这两种技术都能有效避免因为频繁调用函数而导致的性能问题。