当前位置: 首页 > news >正文

使用 Fetch + Streams 处理流式响应(Streaming Response)

使用 Fetch + Streams 处理流式响应(Streaming Response)

📌 一、用途说明

该代码用于从一个支持流式响应的服务器接口读取数据,一般用于:

  • 与 OpenAI、ChatGPT 等模型的实时对话接口
  • 音视频分片下载
  • Server-Sent Events(SSE)或其他长连接传输
  • 后端支持 chunked transfer encoding 的接口

🧩 二、完整代码

try {const response = await fetch("http://127.0.0.1:8000/AI/chat", {method: "POST",headers: {"Content-Type": "application/json"},body: JSON.stringify({ query: content })});const reader = response.body.getReader();const decoder = new TextDecoder();let done = false;let result = '';while (!done) {const { value, done: doneReading } = await reader.read();done = doneReading;let resultString = decoder.decode(value, { stream: true });result += resultString;console.log(resultString);}
} catch (error) {console.error("请求失败:", error);
}

🔍 三、逐项详解

代码片段说明
fetch(...)使用 Fetch API 发起 POST 请求
headers: { "Content-Type": "application/json" }声明请求体是 JSON 类型
JSON.stringify({ query: content })将 JavaScript 对象转换为 JSON 字符串
response.body.getReader()获取 ReadableStream 的读取器(Reader)
TextDecoder()创建一个用于将字节流解码为文本的对象
reader.read()异步读取下一段数据,返回 { value, done }
decoder.decode(value, { stream: true })解码字节为字符串,stream 选项表示多段解码
result += resultString可选,用于累积最终结果
console.log(resultString)打印每次读取的结果,模拟实时输出

🔁 四、类似用法对比

✅ 示例 1:读取流式 JSON 响应

const reader = response.body.getReader();
const decoder = new TextDecoder();
let buffer = "";while (true) {const { value, done } = await reader.read();if (done) break;buffer += decoder.decode(value, { stream: true });try {const json = JSON.parse(buffer);console.log("解析成功:", json);break;} catch (e) {// 继续读取直到 JSON 完整}
}

✅ 示例 2:处理 SSE(Server-Sent Events)事件流

const response = await fetch("/sse");
const reader = response.body.getReader();
const decoder = new TextDecoder();
let partial = "";while (true) {const { value, done } = await reader.read();if (done) break;partial += decoder.decode(value, { stream: true });const events = partial.split("\n\n");for (let i = 0; i < events.length - 1; i++) {const event = events[i];if (event.startsWith("data:")) {const data = event.replace("data: ", "");console.log("收到事件:", data);}}partial = events[events.length - 1];
}

✅ 示例 3:Blob/视频流读取

const response = await fetch("/video");
const reader = response.body.getReader();
let chunks = [];while (true) {const { value, done } = await reader.read();if (done) break;chunks.push(value);
}const blob = new Blob(chunks, { type: "video/mp4" });
document.querySelector("video").src = URL.createObjectURL(blob);

🧠 五、补充知识:TextDecoder 的作用

TextDecoder 是浏览器提供的用于解码 Uint8Array 字节为字符串的 API。

常用方法:

const decoder = new TextDecoder("utf-8");
decoder.decode(Uint8Array, { stream: true });
  • { stream: true }:允许将未完成的字节块保留到下一次调用,防止字符乱码或丢失。

🧰 六、其他工具库推荐

  • react-streaming
  • readable-stream(Node.js)
  • eventsource-parser(处理 SSE)

✅ 七、参考文档

  • MDN: fetch
  • MDN: ReadableStream
  • MDN: TextDecoder
http://www.xdnf.cn/news/734113.html

相关文章:

  • Odoo OWL 框架深度研究(VIP10万字版)
  • 特伦斯 S75 电钢琴:重构演奏美学的极致表达
  • 小黑大语言模型应用探索:langchain智能体构造源码demo搭建1(初步流程)
  • OptiStruct实例:消声器前盖ERP分析(2)RADSND基础理论
  • 深入解析 Redis Cluster 架构与实现(二)
  • 【sa-token】 sa-token非 web 上下文无法获取 HttpServletRequest。
  • 数据结构:导论
  • SpringBatch+Mysql+hanlp简版智能搜索
  • matlab计算转子系统的固有频率、振型、不平衡响应
  • StringBuilder对象的操作
  • cocos creator资源管理器,资源动态加载和释放
  • 基于Qt封装数据库基本增删改查操作,支持多线程,并实现SQLite数据库单例访问
  • 【google 论文】Titans: Learning to Memorize at Test Time
  • 裂缝仪在线监测装置:工程安全领域的“实时守卫者”
  • DrissionPage WebPage模式:动态交互与高效爬取的完美平衡术
  • C# 将HTML文档、HTML字符串转换为图片
  • Window10+ 安装 go环境
  • 深入探索:基于 Nacos 的配置管理之动态配置与环境管理
  • Lifecycle原理
  • 低秩矩阵、奇异值矩阵和正交矩阵
  • 【FlashRAG】本地部署与demo运行(一)
  • ArcGIS应用指南:基于网格与OD成本矩阵的交通可达性分析
  • AI时代的园区网变革:“极简”行至最深处,以太彩光恰自来
  • 【C++】位图
  • 前端pointer-events属性
  • 显卡3080和4060哪个强 两款游戏性能对比
  • 重拾Scrapy框架
  • Clish中xml文件配置的使用方法
  • Spring Cloud Alibaba 学习 —— 简单了解常用技术栈
  • 【专题】神经网络期末复习资料(题库)