WebSocket多消息同时触发同一异步函数的执行限制问题咨询
解决方案
针对同一时间戳的WebSocket消息重复触发异步函数的问题,你可以通过防抖+缓存最新数据的方式,确保同一批次的消息仅执行一次trigger,且使用该批次的最后一条数据。
方案一:简单防抖(适合同批次消息无时间间隔的场景)
这种方式通过短延迟等待同批次消息全部接收,只保留最后一条数据执行:
// 缓存最新待处理数据和定时器ID let latestBatchData = null; let batchTimer = null; connection.on('message', async event => { const data = JSON.parse(event.d); // 覆盖为当前批次的最新数据 latestBatchData = data; // 仅当无定时器时设置延迟,避免重复触发 if (!batchTimer) { batchTimer = setTimeout(async () => { // 执行异步方法,使用最后一条数据的p值 await trigger(latestBatchData.p); // 执行完毕后清空缓存和定时器 batchTimer = null; latestBatchData = null; }, 10); // 延迟时间可根据实际场景调整(5-20ms即可) } });
方案二:按时间戳精确分组(适合多时间戳消息交错的场景)
如果存在不同时间戳的消息可能交错到达的情况,可以按T字段分组缓存,确保每个时间戳的批次仅处理一次:
// 缓存每个时间戳的最新数据 const timestampDataCache = new Map(); // 缓存每个时间戳对应的定时器 const timestampTimerCache = new Map(); connection.on('message', async event => { const data = JSON.parse(event.d); const currentTimestamp = data.T; // 更新当前时间戳的最新数据 timestampDataCache.set(currentTimestamp, data); // 仅当该时间戳无定时器时设置延迟 if (!timestampTimerCache.has(currentTimestamp)) { const timerId = setTimeout(async () => { const targetData = timestampDataCache.get(currentTimestamp); await trigger(targetData.p); // 清理当前时间戳的缓存和定时器 timestampDataCache.delete(currentTimestamp); timestampTimerCache.delete(currentTimestamp); }, 10); timestampTimerCache.set(currentTimestamp, timerId); } });
原理说明
- 短延迟的作用是等待同一批次的所有消息全部到达,确保我们能拿到该批次的最后一条数据。
- 缓存机制用来记录当前需要处理的最新数据,避免重复执行
trigger。 - 定时器的存在确保同一批次内的消息只会触发一次异步方法。
内容的提问来源于stack exchange,提问作者aspirinemaga
相关产品推荐
相关产品推荐

