问题:假设有一个json
对象如下:
{
table: [
{
name: 'js',
age: 20
}
]
}
现在以上对象在服务端被格式化stream流返回(一个请求,分为多个片段返回),并且每个片段的内容都是不确定的,前端接收到内容后,都需要用JSON.parse
解析代码,并渲染到界面上。
假设服务端返回的每个片段可能如下:
// 1
"{"
// 2
"table: ["
// 3
"{name: 'js',"
// 4
"age: 20"
// 5
"}"
// 6
"]"
// 7
"}"
从上面可以看出,服务端每个片段返回到可能是总的json中任意片段长度的字符串,前端需要每次都能解析出来,我的理解是每次都自动拼接对应的后续缺失的}
,]
,'
等。比如收到第一个片段时,自动拼接上}
,此时整体变成{}
就可以直接使用JSON.parse
解析而不会报错,到第二个片段时,应该拼接后变成{ table: [] }
,以此类推,如果某个片段返回了对应}
或者]
则需要移除前面手动拼接的}
和]
。
有没有类似的专门处理以上需求的算法,或者npm包呢。
你可以JSONStream这个库:https://github.com/dominictarr/JSONStream
先安装:
npm install JSONStream
再用JSONStream.parse()方法来解析数据流:
const JSONStream = require('JSONStream');
const request = require('request');
const url = 'http://your-server.com/streaming-json-api';
// 用 request 库获取 JSON 数据流
request(url)
.pipe(JSONStream.parse('table.*'))
.on('data', (data) => {
// 处理解析到的 JSON 片段
console.log('Parsed JSON piece:', data);
});
可以看看这个 https://github.com/creationix/jsonparse。
算法的话,我能想到的就是 Stack,LeetCode 有一道题叫 Valid Parentheses 就是说这个的,只不过这个放在 json string 上面逻辑更复杂一些。
实际上我觉得看你用到什么程度,如果是大概代码能“跑”就行的话,其实不用做到完美拼接那么麻烦,就直接用 JSON.parse
试错迭代就完事儿了。当然为了降低频率,可以简单的进行方括号和花括号的拼接,我随便撸了个简单版本:
const { Readable } = require("node:stream");
const jsonSegmentsRS = Readable.from([
// 1
"{",
// 2
'"table": [',
// 3
'{"name": "js",',
// 4
'"age',
// 5
'": 20}',
// 6
"]",
// 7
"}",
]);
const KeyWords = {
CURLY_BRACE: {
L: "{",
R: "}",
},
SQUARE_BRACKET: {
L: "[",
R: "]",
},
// todo: also needs to resolve the special char, eg: comma
};
class StreamMannerJsonParser {
records = [];
bufferStack = [];
pairStack = [];
parse(segment) {
const chars = segment.replace("s", "").split("");
chars.forEach((c) => {
this.bufferStack.push(c);
switch (c) {
case KeyWords.CURLY_BRACE.L:
case KeyWords.SQUARE_BRACKET.L:
this.pairStack.push(c);
break;
case KeyWords.CURLY_BRACE.R:
if (this.pairStack.at(-1) === KeyWords.CURLY_BRACE.L)
this.pairStack.pop();
break;
case KeyWords.SQUARE_BRACKET.R:
if (this.pairStack.at(-1) === KeyWords.SQUARE_BRACKET.L)
this.pairStack.pop();
break;
}
});
try {
// todo: simple bypass the failed parse action
return JSON.parse(
this.bufferStack
.concat(
[...this.pairStack]
.reverse()
.map((c) =>
c === KeyWords.CURLY_BRACE.L
? KeyWords.CURLY_BRACE.R
: KeyWords.SQUARE_BRACKET.R
)
)
.join("")
);
} catch (err) {
console.warn("warn: parse failed, waiting for another chunk");
}
}
}
const parser = new StreamMannerJsonParser();
jsonSegmentsRS.on("data", (chunk) => {
const parsedChunk = parser.parse(chunk);
typeof parsedChunk !== "undefined" && console.log(parsedChunk);
});
执行结果(改了点你的数据,因为有些地方不是合法的 json 字符串):
我这里为了图省事儿,就当做 string stream 来处理了,实际上真要实现的话,应该用 object mode,然后封装成 Readable Stream(或双工) 直接和响应请求的 Stream pipe 起来就行了。
试试这个叫做clarinet
的库
下面的文章是其中一个使用场景
使用clarinet(browser&node.js)解析不合法的json字符串
arinet会解析json字符串,在每个json字符串关键点触发回调,
始一个object,进入一个key,进入一个value,开始一个array,
利用这些回调,拼装出期望的格式
问题内容: 我正在使用Sencha Touch(ExtJS)从服务器获取JSON消息。我收到的消息是这个: 我的问题是我无法解析此JSON对象,因此我可以使用每个计数器对象。 我正在尝试像这样完成: 我究竟做错了什么 ?谢谢! 问题答案: Javascript具有针对字符串的内置JSON解析,我想这就是您拥有的: 在您的示例中使用此代码将是: 编辑 :for循环的使用中有一个错误(我在初读时就错过
问题内容: 我有一个AJAX调用,返回的是这样的JSON: 在div中,我将得到: 如何遍历此数据并将每个名称放在div中? 问题答案: 假设您的服务器端脚本未设置正确的响应标头,则需要使用参数向jQuery指示这是JSON 。 然后,您可以使用该函数遍历数据: 或使用方法:
主要内容:什么是 JSON,在 JavaScript 中解析 JSON 数据,解析嵌套的 JSON 数据,将数据转换为 JSONJSON 全称为“JavaScript Object Notation”,是当前最流行的一种轻量级的数据交换格式,用来存储和传输数据,通常服务器端与客户端在进行交互时就是使用 JSON 格式的数据。 什么是 JSON JSON 是从 JavaScript 脚本中演变而来的,并且使用 JavaScript 中的语法来描述数据。与 XML 一样,JSON 也是一种基于文本的
问题内容: 我正在使用NewtonsoftJson库来解析json,但我不知道如何使用它。我使用JObject解析了字符串。当我在即时窗口中输出JObject实例的值时,我得到了:- 我应该怎么做才能获得这个工作的价值? 问题答案: 我个人更喜欢将JavaScriptSerializer与.NET环境中的JSON一起使用。默认情况下,它将返回Dictionary结果,但可用于解析到自定义对象(或者
information.json 我想解析这个json文件。 其中,我希望解析'items:[{...}]'内容中的内容但是教程没有告诉我如何做到这一点。 我用Java,但Kotlin也可以(Android) GSON会删除标记吗?还是我该把它移除?如果后者呢?
本文向大家介绍JavaScript处理解析JSON数据过程详解,包括了JavaScript处理解析JSON数据过程详解的使用技巧和注意事项,需要的朋友参考一下 JSON (JavaScript Object Notation)一种简单的数据格式,比xml更轻巧。 JSON 是 JavaScript 原生格式,这意味着在 JavaScript 中处理 JSON 数据不需要任何特殊的 API 或工具包