前言
我们在使用chatgpt这种LLM对话产品的时候,一般和LLM对话返回的结果一般都是一段一段的返回给我们的,而不是一整个直接返回给我们,为什么会出现这种情况呢?赶快来看看吧!
原因分析
我们向LLM提出一个问题,LLM需要分析传给它的数据,并且还要进行概率计算,最终把一系列高概率结果返回给我们用户。
我们用户接收的是来自服务器的数据,而服务器传输数据是一段一段的传给我们的,并不是一下子把数据传输给我们。但是我们前端该怎么实现这样的效果呢?
我们一般都是收集用户的询问问题,然后发送给服务器让它们去处理。如果就这么直接的处理的话,难免要等待响应的结果。但是,随着等待的时间较长,用户端得不到响应的话,用户也会不耐烦,降低了他们的体验。
那么这一切的根源在哪呢?
const url='XXXXX'
async function getResponse(content){
// 发起请求
const resq=await fetch(url,{
method:'POST',
headers:{
'Content-Type':'application/json',
},
body:JSON/stringify({content})
})
// 解析转换为纯文本
const text=await resq.text()
console.log(text)
}
耗时主要在哪?
要想知道花费时间主要在哪,我们就需要对这两个await的作用比较清楚。
我们先来看看流程图
我们客户端最先收服务器的一定是响应头,当用户端接收到响应头后,第一个await就马上结束了。所以说,主要花费的时间就是在第二个await上。而且响应头的内容较少,基本上不怎么花时间。我们第二个await等待的就是那一个个响应体。等全部响应体过来后,第二个await就结束了。
所以,我们对第二个await进行处理,不能一直等到所有的响应体过来。我们应该流式读取,客户端和服务器响应的时候,服务器像水流一样把数据返回给客户端,即服务器端过来多少客户端读多少。
...
const reader = resp.body.getReader()
const decoder = new TextDecoder()
while(1){
// 此处等待,不会等到所有返回,有多少读多少
const [done,value] = await reader.read()
if(done){
break
}
const txt = decoder.decode(value)
// 只需把读到的内容渲染回页面即可
}
Ending
以上内容就是流式读取的解析了。