首页 > 解决方案 > 将流式块数据解析为 JSON

问题描述

嗨,我正在尝试以块的形式显示数据,因为我正在以块的形式获取数据。

例如,让我们假设数据是这样的。

data: {
user: [
    {
        name: 'a',
        bankAccounts: ['123', '234', '567'],
        address: ['some address', 'some other address', 'some more addres']
    },
    {
        name: 'b',
        bankAccounts: ['1233', '2334', '5637'],
        address: ['some address1', 'some other address1', 'some more addres1']
    },
    {
        name: 'c',
        bankAccounts: ['123355', '233455', '563700'],
        address: ['some address12', 'some other address12', 'some more addres12']
    },
]    
}

但我收到的块是这样的

1st chunk: "data: user: [ {name: a"
2nd chunk: "bankAccounts: ['123', '234', '567'],"
3rd chunk: "address: ['some address', 'some other address', 'some more addres']"

and so on..

我以无法转换为 json 的方式接收分块数据,因为它不完整。

如何在 UI 中流式传输这些数据?

任何想法 !!!

My code for fetching streaming data

fetch('some url which stream data')
// Retrieve its body as ReadableStream
    .then(response => {
        const reader = response.body.getReader();
        let decoder = new TextDecoder();
        return new ReadableStream({
        start(controller) {
            return pump();
            function pump() {
                return reader.read().then(({ done, value }) => {
                    // When no more data needs to be consumed, close the stream
                    let newData = decoder.decode(value, {stream: !done});
                    console.log(newData);
                    if (done) {
                        controller.close();
                        return;
                    }
                    // Enqueue the next data chunk into our target stream
                    controller.enqueue(value);
                    return pump();
                });
            }
        }
    })
})
.then(stream => new Response(stream))
.then(response => {
    console.log('response', response)
})

标签: javascriptjsonstreaming

解决方案


我知道生成器不是很常用,但我觉得它们非常适合在此任务中流式传输数据,

async function* streamAsyncIterator(stream) {
  const reader = stream.getReader();
  const decoder = new TextDecoder();
  while (true) {
    const {done,value} = await reader.read();
    if (done) break;
    yield decoder.decode(value, { stream: !done });
  }
  reader.releaseLock();
}

fetch('https://httpbin.org/stream/1')
    .then(async response => {
        let str="";
        for await (const value of streamAsyncIterator(response.body))
            str+=value;
        return JSON.parse(str);
    })
    .then(response => {
        console.log('response', response)
    })

但是,您似乎想要解析部分完整的 JSON,这可以通过多种方式实现,例如使用 npm 库partial-json-parser

import partialParse from 'partial-json-parser';

fetch('https://httpbin.org/stream/1')
    .then(async response => {
        let str="";
        for await (const value of streamAsyncIterator(response.body)){
            str+=value;
            functionUpdatingYourUi(partialParse(str));
        }
        return JSON.parse(str);
    })
    .then(response => {
        console.log('response', response)
    })

推荐阅读