如何修复WebSocket客户端JS代码,规避每秒1次的HTTP请求速率限制
修复WebSocket消息回调中的HTTP请求限流问题
原代码的核心问题是:WebSocket的message事件会为每条消息触发独立的异步回调,这些回调之间完全并行,单个回调里的await延迟只能控制当前回调内的逻辑,无法全局限制所有HTTP请求的发送速率,导致多个回调可能同时发起请求,突破每秒1次的限制。
要解决这个问题,需要用请求队列串行化所有待发送的HTTP请求,确保前一个请求处理完成(或等待够1秒间隔)后,再处理下一个请求。修复后的代码如下:
import WebSocket from "ws" import axios from "axios"; const ws = new WebSocket(`example_url`) let lastRequestTimestamp = 0; // 初始化一个已完成的Promise,作为队列的起始节点 let requestQueue = Promise.resolve(); ws.on("message", function message(data) { // 仅当满足数据条件时,将请求加入队列 if (data.status) { // 通过链式调用Promise,实现请求的串行处理 requestQueue = requestQueue.then(async () => { const now = Date.now(); const interval = now - lastRequestTimestamp; // 距离上次请求不足1秒时,等待剩余时长 if (interval < 1000) { await new Promise(resolve => setTimeout(resolve, 1000 - interval)); } // 发起HTTP请求并等待完成 await axios.post(/* 替换为你的请求URL和参数 */); // 更新最后一次请求的时间戳 lastRequestTimestamp = Date.now(); }).catch(err => { // 捕获请求错误,避免单个失败导致整个队列中断 console.error("HTTP请求出错:", err); }); } })
关键改动说明
- 串行化请求:用
requestQueue变量维护一个Promise链,所有需要发送的HTTP请求都通过.then()加入链中,确保同一时间只有一个请求在处理。 - 正确控制时间间隔:在队列的每个任务中统一处理时间等待逻辑,保证两次请求的间隔至少1秒。
- 等待请求完成:给
axios.post加上await,确保请求真正完成后再更新时间戳,避免后续请求提前触发。 - 错误处理:添加
catch捕获请求错误,防止单个请求失败导致整个队列停止工作。
内容的提问来源于stack exchange,提问作者TungTung
相关产品推荐
相关产品推荐

