Files
chatroom/resources/js/chat-room/message-queue.js
T

67 lines
2.1 KiB
JavaScript
Raw Normal View History

// 聊天室消息队列工具,用于后续迁移接收消息、批量渲染和节流刷新逻辑。
/**
* 创建可控长度的消息队列。
*
* @param {{limit?:number, onFlush?:(messages:unknown[])=>void, scheduler?:(callback:()=>void)=>unknown}} options
* @returns {{enqueue:(message:unknown)=>number, flush:()=>unknown[], scheduleFlush:()=>void, clear:()=>void, size:()=>number, toArray:()=>unknown[]}}
*/
export function createMessageQueue(options = {}) {
const limit = Math.max(Number.parseInt(options.limit, 10) || 200, 1);
const queue = [];
2026-04-25 08:18:01 +08:00
// 标记当前帧是否已排队刷新,避免高频消息在同一帧内重复触发渲染。
let flushScheduled = false;
const scheduler = typeof options.scheduler === "function"
? options.scheduler
: (callback) => {
2026-04-25 08:18:01 +08:00
// 浏览器优先跟随 RAF 合并刷新,测试或无 RAF 环境回退到短 timeout。
const requestFrame = globalThis.requestAnimationFrame || ((handler) => globalThis.setTimeout(handler, 16));
return requestFrame(callback);
};
const flush = () => {
flushScheduled = false;
const messages = queue.splice(0, queue.length);
if (messages.length && typeof options.onFlush === "function") {
options.onFlush(messages);
}
return messages;
};
return {
enqueue(message) {
queue.push(message);
2026-04-25 08:18:01 +08:00
// 队列超过上限时丢弃最旧消息,避免离线积压拖慢后续批量渲染。
while (queue.length > limit) {
queue.shift();
}
return queue.length;
},
flush,
scheduleFlush() {
if (flushScheduled) {
return;
}
flushScheduled = true;
scheduler(flush);
},
clear() {
queue.splice(0, queue.length);
flushScheduled = false;
},
size() {
return queue.length;
},
toArray() {
return [...queue];
},
};
}