fast-api后端 + fetch 前端流式文字响应
- fast-api后台接口
- 前端
-
- [fetch 流式文本数据处理](#fetch 流式文本数据处理)
fast-api后台接口
流式响应
python
from fastapi.responses import StreamingResponse
from tqdm import tqdm
from pydantic import BaseModel
class ItemDataSingle(BaseModel):
data: str
async def responce_text_streammer(data):
_data = data.data
# 假设你发送过来的
data = json.loads(_data)
for dat in tqdm(data):
dat = your_worker_function(dat)
# 给每条数据一个分割标识
yield json.dumps(dat,ensure_ascii=False) + "@@+"
@app.post("/batchtext2furniture")
async def batchtext2furniture(data: ItemDataSingle,):
"""
:arg
"""
# mongodb
return StreamingResponse(responce_text_streammer(data))
前端
fetch 流式文本数据处理
javascript
var req_data = {
data: JSON.stringify({}),//youdata
};
let charsReceived = 0;
const startTime = Date.now();
let result = "";
let num_results = 0;
const decoder = new TextDecoder("utf-8");
fetch("/batchtext2furniture", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: req_data,
stream: true,
})
.then((response) => {
const reader = response.body.getReader();
return new ReadableStream({
async start(controller) {
let resev_s = true;
while (resev_s) {
const { done, value } = await reader.read();
if (done) {
controller.close();
resev_s = false;
break;
}
charsReceived += value.length;
const chunk = value;
result += decoder.decode(chunk);
console.log("Received " + charsReceived + " characters");
const responseTime = (Date.now() - startTime) / 1000;
num_results += 1;
if (result.endsWith("@@+")) {
console.log("接收到分割符号");
let parts = result.split("@@+");
let lastPart = parts[parts.length - 2];
// 解析 JSON
var json_data = JSON.parse(lastPart);
// 前端具体对每段数据的处理
// ......
} else {
console.log("not endswith @@+");
}
console.log("数据赋值完成" );
controller.enqueue(value);
}
},
});
})
.then((stream) => {
console.log(stream);
console.log(stream, "stream");
console.log(stream.size);
})
.catch((error) => {
console.error("Error:", error);
})
.finally(() => {
yourfinallyworker();
});
const endTime = Date.now();
console.log(endTime - startTime, "搜索时间");
}