javascript - 将流式块数据解析为 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)
})
解决方案
我知道生成器不是很常用,但我觉得它们非常适合在此任务中流式传输数据,
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)
})
推荐阅读
- drupal - Drupal 允许多个用户添加和修改内容
- node.js - 尝试部署 rails/react 应用程序时应用程序与 buildpack 不兼容
- wordpress - 致命错误:无法制作非静态方法
- highcharts - HighCharts 在新标签页中打开链接
- qt - How use QT Creator and Squish COCO
- python - 将简单的 Socket.io Flask 应用程序部署到 Google App Engine:仍未解决
- python - Python - LinAlgError:SVD 未在线性最小二乘中收敛 - 数据中没有 Nans 或 infs
- r - 等效的 ggplot2 替代 gplots 的气球图?
- mysql - MySQL查询大于等于24小时的行
- javascript - 表单数据未到达数据库