Chunk(数据块) 协议
别名:
数据块
流式传输中一次 `read()` 拿到的字节片段。**chunk 边界不对齐行边界**:一个完整事件可能被切进多个 chunk,必须用半行 buffer 攒齐 `\n\n` 再分帧。
它是什么
Chunk(数据块)是流式响应中一次 reader.read() 拿到的字节片段。ReadableStream 就像一根水管,数据不是一次给完,而是分成一块一块流过来;每次 read() 返回 { value, done },value 就是一个 Uint8Array。
最大的坑:边界不对齐
网络从不保证「一个 chunk = 一个完整事件」:一次可能发来 data: {"choices":[{"delta":{"conten,下一个 TCP 包才是 t":"你"}}]}\n\n——一个 JSON 行被切成两半。天真地认为每次 read() 拿到一整行,就会把 conten 当事件去 JSON.parse 而报错。
解法是半行 buffering:不管 chunk 从哪切,先全部拼进一个 buffer,只在看到 \n\n(事件结束标志)时才切出完整事件处理;剩下的残渣留回 buffer 等下一个 chunk 补齐。
与 TextDecoder 的分工
还有一个容易混的坑:TextDecoder.decode(value, { stream: true }) 解决的是「半个字符」问题(一个多字节 UTF-8 字符被切成两半),buffer 解决的是「半个事件」问题,两者都要——前者在解码层、后者在分帧层。