Fetch 的 response.body 是 ReadableStream,需用 getReader() 获取读取器并循环调用 read() 逐块读取 Uint8Array;须检查 response.ok、处理 null body、复用 TextDecoder、拼接缓冲区以应对跨 chunk 边界,并妥善捕获错误及调用 cancel() 释放资源。

Fetch 的 response.body 是一个 ReadableStream,天然支持流式读取分块数据。关键在于用 getReader() 获取流读取器,再循环调用 reader.read() 逐块获取 Uint8Array 数据,而不是一次性调用 response.text() 或 response.json()。
获取并初始化流读取器
发起 fetch 后,从 response.body 创建读取器,并确保响应状态正常:
- 必须检查
response.ok或response.status,流读取不会自动抛出 HTTP 错误 - 调用
response.body.getReader()得到ReadableStreamDefaultReader - 若响应无 body(如 204),
response.body可能为null,需提前判断
循环读取分块数据(基于 promise)
使用 reader.read() 返回的 Promise 解构 { done, value }:
-
done为true表示流已结束,循环终止 -
value是Uint8Array,即当前 chunk 的原始字节 - 可直接转为字符串:
new TextDecoder().decode(value)(推荐 UTF-8) - 避免在每次读取中新建
TextDecoder,应复用实例提升性能
处理文本流(如 SSE、长 JSON、日志流)
服务端按行或按帧推送时,需自行拼接、切分缓冲区:
立即学习“Java免费学习笔记(深入)”;
- 维护一个
decoder和一个buffer(如''或new Uint8Array()) - 每次读到
value就追加解码后的内容到缓冲字符串,再按\n分割处理完整行 - 注意处理跨 chunk 的换行符(如一行数据被切在两个 chunk 中),需保留未完成行到下次读取
- 若服务端用
text/event-stream,每行以data:开头,需按 SSE 协议解析
错误处理与流关闭
流读取过程可能因网络中断、取消请求或服务端异常而失败:
-
reader.read()拒绝的 Promise 会抛出错误,需用try/catch或.catch() - 主动取消时调用
reader.cancel(),它返回 Promise,可 await 确保清理完成 - 读取结束后,
reader.releaseLock()并非必需,但显式调用有助于明确资源释放意图 - 不建议手动
controller.close()—— 流由浏览器管理,应用只需消费完即可
流式读取的核心是“按需解包”,不缓存整条响应体,内存友好且响应及时。只要正确处理 chunk 边界和编码,就能稳定支撑实时日志、SSE、大文件分段下载等场景。


















