fast-api后端 + fetch 前端流式文字响应
fast-api后台接口
流式响应
from fastapi.responses import StreamingResponse
from tqdm import tqdm
from pydantic import BaseModelclass ItemDataSingle(BaseModel):data: strasync def responce_text_streammer(data): _data = data.datadata = 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"""return StreamingResponse(responce_text_streammer(data))
前端
fetch 流式文本数据处理
var req_data = {data: JSON.stringify({}),};
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];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, "搜索时间");}