在 javascript 中异步使用分块数据
Posted
技术标签:
【中文标题】在 javascript 中异步使用分块数据【英文标题】:Consuming chunked data asyncrhonously in javascript 【发布时间】:2018-08-18 19:16:57 【问题描述】:我有一个 (GET) 端点,它以块的形式发送数据 (Transfer-Encoding: chunked
)。数据采用 JSON 编码并逐行发送。
有没有办法在 javascript 中(或使用某些 JavaScript 库)以异步方式使用此端点发送的数据?
明确地说,我知道如何执行异步GET
,但我希望GET
请求不等待整个数据传输,而是在数据到达时逐行读取.例如,当这样做时:
curl http://localhost:8081/numbers
下面的行在可用时一一显示(我制作的示例服务器在发送一行和第二个之间等待一秒钟)。
"age":1,"name":"John"
"age":2,"name":"John"
"age":3,"name":"John"
"age":4,"name":"John"
我想在浏览器中重现 curl
的相同行为。我不想让用户等到所有数据都可用才能显示任何内容。
【问题讨论】:
未来的答案可能是developer.mozilla.org/en-US/docs/Web/API/Streams_API 谢谢!这就是为什么我在任何地方都找不到这个问题的答案。 Streams_API 看起来不会很快出现在 Firefox 中,但 ReadableStream 已经可以使用 Fetch API。你可能会觉得 this article on how to handle streams with Fetch API 很有趣。 该死!我希望在重新实现端点以使用服务器发送的事件之前看到你的答案:) 我要试试ReadableStream
。
对,你可以在服务器端节省一些工作量和 websockets 库依赖。
【参考方案1】:
感谢Dan 和Redu,我能够使用Fetch API 组合一个增量使用数据的示例。需要注意的是,这在 Internet Explorer 上不起作用,并且必须由用户在 Firefox 中启用:
/** This works on Edge, Chrome, and Firefox (from version 57). To use this example
navigate to about:config and change
- dom.streams.enabled preference to true
- javascript.options.streams to true
See https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream
*/
fetch('http://localhost:8081/numbers').then(function(response)
console.log(response);
const reader = response.body.getReader();
function go()
reader.read().then(function(result)
if (!result.done)
var num = JSON.parse(
new TextDecoder("utf-8").decode(result.value)
);
console.log(
"Got number " + num.intVal
);
go ();
)
go ();
)
完整示例(带有服务器)在at my sandbox 可用。我发现将这个版本与不使用fetch
API 的this one 进行比较可以说明XMLHttpRequest
的局限性。
【讨论】:
很高兴看到您使用ReadStream
解决了这个问题。只需一个快速提醒;与 Haskell 不同,在 JS 中,在生产代码中使用递归可能会变得很危险,因为如果您有 200K+ 块要读取,您的调用堆栈最终可能会被炸毁。因此,如果您提前知道块数,您不妨用reader.read()
承诺填充该大小的数组,然后通过减少数组、对承诺进行排序来链接它们的.then()
阶段。只是一个想法。
感谢Redu的提醒。我花了太多时间做 Haskell :)
请注意,不能保证body
流将在一次读取中为您提供完整的块 (***.com/questions/57412098/…)。使用 NDJSON 可能会更好(缓冲解码的文本,直到你点击换行符,然后解析缓冲区中的 JSON 直到那时)。
@Vidar 你的回答几乎涵盖了每个用例,但我很难将 ndjson 解析应用到我的读者,你有任何使用示例吗?
@moxched 这可能会有所帮助:github.com/deanhume/streams以上是关于在 javascript 中异步使用分块数据的主要内容,如果未能解决你的问题,请参考以下文章
javascript异步编年史,从“纯回调”到Promise