[英]Fail to parse on a json stream using node-fetch
我從node-fetch
stream 功能運行示例代碼。 有時它可以成功解析塊,有時返回錯誤消息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()
有人知道為什么嗎? 我可以依靠大塊嗎?
通過請求https://httpbin.org/stream/3
,服務器通過 stream 發送分成 3 個塊的數據。客戶端(在本例中是您的節點腳本)保持與服務器的連接並繼續接收數據並將它們分成塊。
每次完成單個異步任務時, node-fetch
只是將數據分成塊,如您在此處所見: body.js 的第 199 行。
因此,如果拆分后的數據到達速度如此之快,以至於異步任務在單個節點的事件循環中接收到多個數據塊, node-fetch
接收到多個 jason 數據。
那是錯誤發生的時候。 在添加了console.log
的情況下運行以下代碼。 然后你可以確認當錯誤發生時,多個 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()
對於本站,報錯時可以自行拆分數據如下。
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()
當您在瀏覽器中使用 Fetch API 時,您實際上可以編寫自己的ReadableStreamReader並實現如何處理拆分數據的策略。
更新:
您可以簡單地使用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.