最近做了一个demo,是有关gpt的流式文本输出,分为两个版本,一个是纯文本A,另一个是含数学公式等特殊文本的版本B。目前,A效果还不错,B能实现但是有缺憾;B只能在公式的latex全部输出完后才能转化为数学公式。如果B的返回结果比较长,那么一大段串的latex输出却迟迟不能转化为公式,这使用体验就差了点,目前还未解决,在想办法。
以下为目前两个版本
A
<script setup lang="ts">
import {onMounted, ref} from "vue";const displayContent = ref<string>('');
const currentIndex = ref<number>(0);const handleDisplayContent = (content: string) => {const delay = 50const tick = () => {if (currentIndex.value < content.length) {displayContent.value += content.charAt(currentIndex.value);currentIndex.value++;setTimeout(tick, delay);}}tick();
}onMounted(async () => {try {const response = await fetch('https://api.xygeng.cn/one');if (!response.body) return;const reader: ReadableStreamDefaultReader<Uint8Array> = response.body.getReader();//stream读取let receivedContent = '';const decoder: TextDecoder = new TextDecoder();//文本解码器, 用于将二进制数据转换为文本while (true) {const {done, value} = await reader.read();//value为二进制if (done) break;receivedContent += decoder.decode(value, {stream: true});}let json2ObjectContent = JSON.parse(receivedContent).data.content;//将json字符串转换为对象,并取得content字段handleDisplayContent(json2ObjectContent);} catch (error) {console.error("fetch请求错误:", error);}
});</script><template><div v-html="displayContent"></div>
</template><style scoped lang="scss">
/* 添加样式以美化输出 */
</style>
B
<script setup lang="ts">
import {onMounted, ref, nextTick} from "vue";
import Mathjax from "@/utils/mathjax.ts";const displayContent = ref<string>('');
const currentIndex = ref<number>(0);// 处理文本显示
const handleDisplayContent = (content: string) => {const delay = 5;const tick = async () => {if (currentIndex.value < content.length) {displayContent.value += content.charAt(currentIndex.value);currentIndex.value++;setTimeout(tick, delay);} else if (currentIndex.value === content.length) {await nextTick(() => {if (Mathjax.isMathjaxConfig) {Mathjax.initMathjaxConfig();}Mathjax.MathQueue('.displayViewContainer');});}};tick();
};onMounted(async () => {try {const response = await fetch('http://127.0.0.1:3007/api/test', {method: 'POST'});if (!response.body) return;const reader: ReadableStreamDefaultReader<Uint8Array> = response.body.getReader(); // stream读取let receivedContent = '';const decoder: TextDecoder = new TextDecoder(); // 文本解码器, 用于将二进制数据转换为文本while (true) {const {done, value} = await reader.read(); // value为二进制if (done) break;receivedContent += decoder.decode(value, {stream: true});}let json2ObjectContent = JSON.parse(receivedContent).content; // 将json字符串转换为对象, 并取得content字段handleDisplayContent(json2ObjectContent);} catch (error) {console.error("fetch请求错误:", error);}
});
</script><template><div class="displayViewContainer" v-html="displayContent"></div>
</template><style scoped lang="scss"></style>