You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JavaScript中如何对WebSocket接收事件排队实现限速执行?

WebSocket 事件限频队列实现(最高每秒处理1次)

核心思路

基于Promise链式调用实现无依赖任务队列,保证所有WebSocket推送事件按到达顺序串行执行,同时通过时间差校验强制两次处理的最小间隔为1秒,既不会丢失事件,也不会因为事件推送频率过高导致处理逻辑过载。

  • 无任何第三方依赖,全部使用原生JS语法实现
  • 事件严格按到达顺序执行,不会出现乱序、并发问题
  • 自动适配业务逻辑耗时:如果单条事件处理本身耗时超过1秒,下一条会在处理完成后立即执行,无额外等待开销
  • 瞬时高流量下的事件自动排队,不会丢失

完整实现代码

// 队列初始值为已完成的Promise,作为链式调用的起点
let taskQueue = Promise.resolve();
// 记录上一次事件处理完成的时间戳
let lastProcessFinishTime = 0;
// 配置最小处理间隔,单位毫秒,1000ms即每秒最多处理1次
const MIN_PROCESS_INTERVAL = 1000;

const ws = new WebSocket(`wss://hallo.com/ws/`);
ws.onmessage = readMessage;

/**
 * 任务入队方法:将新任务追加到队列尾部
 * @param {() => Promise<void>} task 异步处理任务
 */
function enqueue(task) {
  taskQueue = taskQueue.then(task);
}

async function readMessage(event) {
  // 所有收到的事件统一入队,不直接执行业务逻辑
  enqueue(async () => {
    // 计算需要等待的间隔时间
    const currentTime = Date.now();
    const needWait = Math.max(0, MIN_PROCESS_INTERVAL - (currentTime - lastProcessFinishTime));
    // 等待至满足间隔要求
    if (needWait > 0) {
      await new Promise(resolve => setTimeout(resolve, needWait));
    }

    // 以下替换为实际的事件处理逻辑
    print(event) 
    //do important things

    // 更新最后处理完成时间
    lastProcessFinishTime = Date.now();
  })
}

原理解释

参考方案的核心就是Promise链式队列逻辑:通过维护一个始终指向队列最后一个任务的Promise变量,每次新任务入队时就把任务挂载到当前Promise的then回调上,再把这个新返回的Promise更新为队列的尾部节点,天然就能保证所有入队任务按顺序串行执行,不需要手动实现数组队列的轮询逻辑。
在此基础上增加时间间隔校验:每个任务执行前先计算和上一次任务完成的时间差,如果间隔不足1秒就等待补足,即可严格实现最高1次/秒的处理频率限制。


内容的提问来源于stack exchange,提问作者Norbert

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 14:18:27