核心是边接收、边解码、边解析,不等全部响应完成;需校验响应有效性、获取可读流读取器,用 textdecoder 流式解码并缓冲,按 ndjson 或 partial-json 策略渐进解析,配合 abortcontroller 和异常处理保障健壮性。

核心是边接收、边解码、边解析,不等全部响应完成。关键在于绕过 response.text() 或 response.json() 这类全量方法,直接操作底层 ReadableStream,配合 TextDecoder 和渐进式解析逻辑处理中间态数据。
获取并校验可读流
发起 fetch 后,不能直接调用全量解析方法:
- 检查
response.ok === true且状态码在200–299范围内 - 确认
response.body存在且为ReadableStream实例(重定向或空响应可能返回null) - 立即调用
response.body.getReader()获取读取器,避免后续被其他方法锁定
逐块读取与增量解码
使用 while(true) 循环持续拉取二进制块,并安全转为字符串:
- 每次
reader.read()返回{ done, value: Uint8Array },value是原始字节块 - 用
new TextDecoder('utf-8', { stream: true })解码,stream: true可缓存截断的 UTF-8 字符(如中文末尾半个字节) - 将每次
decode()结果追加到全局字符串缓冲区,不急于解析 - 当
done === true时跳出循环,对剩余缓冲区做终态处理
按格式选择渐进解析策略
标准 JSON.parse() 无法处理未闭合结构,需适配数据流格式:
- 若为 NDJSON(每行一个 JSON),按
\n分割后逐行JSON.parse(),失败则跳过该行 - 若为连续 JSON 对象(如
{"a":1,"b":),使用partial-json-parser-js等库,它能在字段不完整时返回已确定部分 - 解析成功后立刻交付结果(如渲染、写入文件、触发事件),无需等待整条流结束
保障健壮性与资源清理
流式过程易受中断、取消、解码异常影响,必须主动兜底:
- 创建
AbortController,传入fetch({ signal }),调用abort()可同时终止请求和读取器 - 所有
reader.read()调用包裹try/catch,捕获TypeError(如流被取消)或DOMException - 在
finally或catch中显式调用reader.cancel(),释放底层资源 - 对解析失败的缓冲区片段,记录偏移位置,继续尝试后续内容,避免单点错误阻塞整条流











