前端如何接收流式数据?

作者站长头像
站长
· 阅读数 4

像一些大模型的 API,有的提供了流式的 API,允许一个字一个字来吐出数据。前端应该使用这些 API?

回复
1个回答
avatar
test
2024-06-25

前端数据的返回本来就是流式返回的,不过通常情况下我们需要的是完整的响应体。如果需要类似于ChatGPT那种流式的返回,只需要将请求的响应体等待去掉就可以。要理解下面代码的两次await的作用:

async function getRes(content) {
  const res = await fetch(url, {...});
  const data = await res.text();
  return data;
}

这里的第一个await是在等待服务器的响应,也就是服务器响应头到达客户端后,第一个await就会结束。

第二个await是在等待所有的响应体到达。

如果要流式读取,只需要修改第二个await的处理:

async function getRes(content) {
  const res = await fetch(url, {...});
  const reader = res.body.getReader();
  // 读取数据流的第一块数据,done表示数据流是否完成,value表示当前的数
  const {done, value} = await reader.read();
  // 上面读取到的是数据的字节码,还需要处理字节码为文本
  const decoder = new TextDecoder();
  const text = decoder.decode(value);
  // 打印第一块的文本内容
  console.log(text, done);
}

上面的示例只读了第一块数据,通过循环来完成所有流数据的读取:

async function getRes(content) {
  const res = await fetch(url, {...});
  const reader = res.body.getReader();
  const decoder = new TextDecoder();
  while(1) {
    // 读取数据流的第一块数据,done表示数据流是否完成,value表示当前的数
    const {done, value} = await reader.read();
    if (done) break;
    const text = decoder.decode(value);
    // 打印第一块的文本内容
    console.log(text, done);
  }
}
回复
likes
适合作为回答的
  • 经过验证的有效解决办法
  • 自己的经验指引,对解决问题有帮助
  • 遵循 Markdown 语法排版,代码语义正确
不该作为回答的
  • 询问内容细节或回复楼层
  • 与题目无关的内容
  • “赞”“顶”“同问”“看手册”“解决了没”等毫无意义的内容