64 lines
1.8 KiB
JavaScript
64 lines
1.8 KiB
JavaScript
|
|
// 聊天室消息队列工具,用于后续迁移接收消息、批量渲染和节流刷新逻辑。
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 创建可控长度的消息队列。
|
||
|
|
*
|
||
|
|
* @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 = [];
|
||
|
|
let flushScheduled = false;
|
||
|
|
|
||
|
|
const scheduler = typeof options.scheduler === "function"
|
||
|
|
? options.scheduler
|
||
|
|
: (callback) => {
|
||
|
|
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);
|
||
|
|
|
||
|
|
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];
|
||
|
|
},
|
||
|
|
};
|
||
|
|
}
|