You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将流式API返回的JSON分块拆分为独立JSON对象?

解决流式API多段JSON解析问题

核心思路

流式API返回的chunk可能拆分在任意位置(比如单个JSON被拆成多个chunk,或一个chunk包含多个完整JSON),因此需要:

  • 维护缓冲区累积未处理字符
  • 通过括号计数器识别完整JSON对象(兼容嵌套对象场景)
  • 解析完整JSON后加入结果集,剩余字符留到下一轮处理

修改后的代码

const getProductData = async (url: string) => {
  const results: any[] = [];
  let buffer = ''; // 累积未处理的字符缓冲区
  let braceCount = 0; // 跟踪大括号嵌套层级
  let startIndex = 0; // 当前待解析JSON的起始位置

  try {
    const response = await fetch(url);
    if (!response.body) return results;

    const stream = response.body.pipeThrough(new TextDecoderStream());
    const reader = stream.getReader();

    while (true) {
      const { value, done } = await reader.read();
      if (done) {
        // 处理最后剩余的缓冲区内容
        if (buffer.trim()) {
          try {
            const json = JSON.parse(buffer.trim());
            results.push(json);
          } catch (e) {
            console.error("解析最后剩余内容失败:", e);
          }
        }
        return results;
      }

      if (value) {
        buffer += value;
        // 遍历缓冲区寻找完整JSON
        for (let i = startIndex; i < buffer.length; i++) {
          const char = buffer[i];
          if (char === '{') {
            braceCount++;
          } else if (char === '}') {
            braceCount--;
            // 大括号层级归0,说明找到完整JSON对象
            if (braceCount === 0) {
              const jsonStr = buffer.slice(startIndex, i + 1).trim();
              try {
                const json = JSON.parse(jsonStr);
                results.push(json);
              } catch (e) {
                console.error("解析JSON失败:", e, "内容:", jsonStr);
              }
              // 更新起始位置,跳过已处理内容
              startIndex = i + 1;
            }
          }
        }
        // 清理已处理的缓冲区内容,优化内存
        if (startIndex > 0) {
          buffer = buffer.slice(startIndex);
          startIndex = 0;
          braceCount = 0;
        }
      }
    }
  } catch (e) {
    console.error("请求或流处理失败:", e);
    return results;
  }
};

关键细节说明

  • 缓冲区管理:避免拆分的JSON片段无法解析,确保所有字符都被累积到完整JSON出现时再处理
  • 嵌套兼容:通过计数器跟踪{和}的数量,即使JSON包含嵌套对象也能准确识别完整边界
  • 错误隔离:单个JSON解析失败不影响后续内容处理,方便排查问题
  • 内存优化:及时截断已处理的缓冲区内容,防止内存占用过高

简化场景提示

如果确认API返回的JSON没有嵌套对象,也可以用更简单的方式:将所有chunk拼接后按/}\s*{/分割,再给每个片段补全大括号后解析,但嵌套场景下计数器方法更可靠。

内容的提问来源于stack exchange,提问作者BreenDeen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 06:47:04