[英]Fail to parse on a json stream using node-fetch
I run the sample code from node-fetch
stream feature.我从
node-fetch
stream 功能运行示例代码。 Sometime it can successfully parse the chunk, sometimes return error msg SyntaxError: Unexpected token { in JSON at position 312
有时它可以成功解析块,有时返回错误消息
SyntaxError: Unexpected token { in JSON at position 312
const fetch = require('node-fetch');
async function main() {
const response = await fetch('https://httpbin.org/stream/3');
try {
for await (const chunk of response.body) {
console.log(JSON.parse(chunk.toString()));
}
} catch (err) {
console.error(err.stack);
}
}
main()
Anyone know why?有人知道为什么吗? Can I rely on the chunk?
我可以依靠大块吗?
By requesting https://httpbin.org/stream/3
, the server sends the data splitting into 3 chunks via stream. The client (in this case your node script) keeps connection with the server and keep receiving the data and splits them into chunks.通过请求
https://httpbin.org/stream/3
,服务器通过 stream 发送分成 3 个块的数据。客户端(在本例中是您的节点脚本)保持与服务器的连接并继续接收数据并将它们分成块。
The node-fetch
simply splits data into chunks every time when a single asynchronous task is completed as you can see here: line 199 of body.js .每次完成单个异步任务时,
node-fetch
只是将数据分成块,如您在此处所见: body.js 的第 199 行。
So if the splitted data arrives so quickly that the asynchronous task receives multiple chunks of data within a single node's event loop, node-fetch
receives multiple jason data.因此,如果拆分后的数据到达速度如此之快,以至于异步任务在单个节点的事件循环中接收到多个数据块,
node-fetch
接收到多个 jason 数据。
That's when the error occurs.那是错误发生的时候。 Run the following code with
console.log
added.在添加了
console.log
的情况下运行以下代码。 Then you can confirm that when error occurs, the multiple jason objects are kept in a chunk
.然后你可以确认当错误发生时,多个 jason 对象被保存在一个
chunk
中。
const fetch = require('node-fetch');
async function main () {
const response = await fetch('https://httpbin.org/stream/3');
try {
for await (const chunk of response.body) {
console.log("------chunk-----\n", chunk.toString());
console.log("Char at 310 -- 315", chunk.toString().substring(310, 315));
console.log(JSON.parse(chunk.toString()));
}
} catch (err) {
console.error(err.stack);
}
}
main()
For this site, you can split the data by yourself when the error occurs as follows.对于本站,报错时可以自行拆分数据如下。
const fetch = require('node-fetch');
async function main () {
const response = await fetch('https://httpbin.org/stream/3');
try {
for await (const chunk of response.body) {
try {
console.log(JSON.parse(chunk.toString()));
} catch (_) {
console.log("------ Handling multiple chunks ------");
chunk.toString().split("\n").slice(0, -1).forEach(d => console.log(JSON.parse(d)));
}
}
} catch (err) {
console.error(err.stack);
}
}
main()
When you use Fetch API with a browser, you can actually write your own ReadableStreamReader and implement the strategy how to handle the splitted data.当您在浏览器中使用 Fetch API 时,您实际上可以编写自己的ReadableStreamReader并实现如何处理拆分数据的策略。
Update:更新:
You can simply use stream-json
library's jsonl Parser as follows:您可以简单地使用
stream-json
库的jsonl Parser ,如下所示:
const { parser: jsonlParser } = require('stream-json/jsonl/Parser');
async function main () {
const response = await fetch('https://httpbin.org/stream/5');
response.body.pipe(jsonlParser())
.on('data', ({ key, value }) => console.log(value))
.on('end', () => console.log("Parsing done."))
.on('error', err => console.log(err.message));
}
main();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.