chatgpt流式文本输出(纯文本+特殊文本)

最近做了一个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 = 50

  const 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>
posted @ 2024-12-24 09:42  yapi_wwj  阅读(259)  评论(0)    收藏  举报