js实现防洪
防抖(Debounce)实现
防抖的核心思想是在事件触发后延迟执行回调函数,若在延迟时间内再次触发事件,则重新计时。适用于输入框搜索、窗口调整等场景。

function debounce(func, delay) {
let timeoutId;
return function(...args) {
clearTimeout(timeoutId);
timeoutId = setTimeout(() => {
func.apply(this, args);
}, delay);
};
}
// 使用示例
const input = document.getElementById('search-input');
input.addEventListener('keyup', debounce(function() {
console.log('Searching for:', input.value);
}, 500));
节流(Throttle)实现
节流的核心思想是在固定时间间隔内只执行一次回调函数。适用于滚动事件、鼠标移动等高频触发场景。

function throttle(func, limit) {
let inThrottle;
return function(...args) {
if (!inThrottle) {
func.apply(this, args);
inThrottle = true;
setTimeout(() => inThrottle = false, limit);
}
};
}
// 使用示例
window.addEventListener('scroll', throttle(function() {
console.log('Scrolling...');
}, 1000));
请求限流(Rate Limiting)
对于API请求,可通过令牌桶算法实现限流,控制单位时间内的请求数量。
class RateLimiter {
constructor(limit, interval) {
this.limit = limit;
this.interval = interval;
this.queue = [];
this.tokens = limit;
setInterval(() => this.refillTokens(), interval);
}
refillTokens() {
this.tokens = Math.min(this.limit, this.tokens + 1);
this.processQueue();
}
processQueue() {
while (this.tokens > 0 && this.queue.length > 0) {
const request = this.queue.shift();
this.tokens--;
request.resolve(request.fn());
}
}
enqueue(fn) {
return new Promise((resolve) => {
this.queue.push({ fn, resolve });
this.processQueue();
});
}
}
// 使用示例
const limiter = new RateLimiter(5, 1000); // 每秒5次请求
async function makeRequest() {
return limiter.enqueue(() => fetch('https://api.example.com'));
}
批量处理(Batching)
对于高频触发的事件(如实时日志),可通过批量处理减少操作次数。
function createBatcher(processBatch, batchSize = 10, timeout = 1000) {
let batch = [];
let timer = null;
function flush() {
processBatch([...batch]);
batch = [];
clearTimeout(timer);
timer = null;
}
return function(item) {
batch.push(item);
if (batch.length >= batchSize) {
flush();
} else if (!timer) {
timer = setTimeout(flush, timeout);
}
};
}
// 使用示例
const logBatcher = createBatcher((logs) => {
console.log('Batch logs:', logs);
});
document.addEventListener('click', (e) => logBatcher(e.target));
注意事项
- 防抖和节流的区别:防抖在连续触发时只执行最后一次,节流在固定间隔执行。
- 请求限流需考虑分布式环境下的同步问题,单机方案可使用Redis等中间件扩展。
- 批量处理的超时时间和批次大小需根据实际场景调整。





