feat: 长文本在详情页面中的消息流式输出
This commit is contained in:
52
src/utils/StreamManager.js
Normal file
52
src/utils/StreamManager.js
Normal file
@@ -0,0 +1,52 @@
|
||||
// 简单的流式数据管理器:开启流、更新流、订阅流、关闭流
|
||||
const streams = {};
|
||||
|
||||
function openStream(id, initial = '', finished = false) {
|
||||
if (!id) return;
|
||||
streams[id] = streams[id] || { text: '', finished: false, subs: new Set() };
|
||||
streams[id].text = initial || '';
|
||||
streams[id].finished = !!finished;
|
||||
// notify existing subscribers
|
||||
streams[id].subs.forEach((cb) => cb(streams[id].text, streams[id].finished));
|
||||
}
|
||||
|
||||
function updateStream(id, text, finished = false) {
|
||||
if (!id || !streams[id]) return;
|
||||
streams[id].text = text || '';
|
||||
streams[id].finished = !!finished;
|
||||
streams[id].subs.forEach((cb) => cb(streams[id].text, streams[id].finished));
|
||||
}
|
||||
|
||||
function subscribe(id, cb) {
|
||||
if (!id) return () => {};
|
||||
streams[id] = streams[id] || { text: '', finished: false, subs: new Set() };
|
||||
streams[id].subs.add(cb);
|
||||
// send current snapshot immediately
|
||||
cb(streams[id].text, streams[id].finished);
|
||||
return () => {
|
||||
streams[id] && streams[id].subs.delete(cb);
|
||||
// 移除空流
|
||||
if (streams[id] && streams[id].subs.size === 0 && streams[id].finished) {
|
||||
delete streams[id];
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function closeStream(id) {
|
||||
if (!id || !streams[id]) return;
|
||||
streams[id].subs.forEach((cb) => cb(streams[id].text, true));
|
||||
delete streams[id];
|
||||
}
|
||||
|
||||
function getSnapshot(id) {
|
||||
if (!id || !streams[id]) return { text: '', finished: false };
|
||||
return { text: streams[id].text, finished: streams[id].finished };
|
||||
}
|
||||
|
||||
export default {
|
||||
openStream,
|
||||
updateStream,
|
||||
subscribe,
|
||||
closeStream,
|
||||
getSnapshot,
|
||||
};
|
||||
Reference in New Issue
Block a user