如何用JavaScript实现请求队列,避免高频API调用被限流?
我在做一个实时搜索功能,输入框每输入一个字符就触发API请求,但发现输入太快会被后端限流。之前用防抖处理过,但用户希望稍微停顿就能立即搜索,所以改成节流,但发现如果用户连续快速输入三次,还是会发三个请求。
我尝试用队列管理请求,写了个简单队列:
let queue = [];
function enqueueRequest(query) {
queue.push(query);
if (!timeout) {
timeout = setTimeout(() => {
const next = queue.shift();
sendRequest(next);
timeout = null;
}, 0);
}
}
但发现当快速输入时,队列里的请求还是同时发出去了,后端返回了429错误。是不是队列没有控制并发?或者我的setTimeout用法有问题?有没有更好的实现方式能保证每次只发一个请求,后面自动排队?
setTimeout,但如果前面的请求还没返回,后面的又会接着发,这就导致后端看到多个请求同时到达。我之前也碰到过类似问题,后来改成了这样:每次只发送队列里的第一个请求,等这个请求完成后再处理下一个。可以用
Promise来监听请求的状态,确保是串行执行。下面是改进后的代码:
这样写后,无论用户输入多快,都只会保证一个请求完成后再发下一个。你可以试试看,应该不会再出现429了。
对了,顺便说一句,这种方式确实能解决限流问题,但用户体验上可能会稍有延迟,毕竟要等前一个请求完成。如果还想优化体验,可以结合防抖或者适当减少队列长度,根据实际情况调整。