fetch 文件流
*"If you stream it, you can do it" -- Walt Disney[^1] *
*“如果您流式传输,就可以做到”-沃尔特·迪斯尼[^ 1] *
Streams are trickling into the scene as we search for ways to improve performance. What if instead of waiting for our entire ajax response to complete, we could start showing the data as it arrives?
当我们寻找提高性能的方法时,信息流正在滴入现场。 如果不用等待我们的整个 ajax响应完成,而是可以在数据到达时开始显示数据呢?
Streams allow us to do this. They are a data source that can be created and processed incrementally. This means as chunks of data become available, we are able to do work on them right away.
流允许我们执行此操作。 它们是可以增量创建和处理的数据源。 这意味着随着大量数据的可用,我们能够立即对其进行处理。
Using the Fetch API with a data format called NDJSON that breaks larger JSON objects into smaller JSON objects delimitated by newline characters, we are able to receive a stream of smaller chunks of JSON data as a stream. As our NDJSON data is streaming in, we can start processing and rendering right away. This makes users happy because they are able to see things sooner and developers happy because it increases overall performance. If you tie all of this in with service workers, then you can really see the improvements in performance.
使用Fetch API和称为JSONJSON的数据格式将较大的JSON对象分解为由换行符分隔的较小的JSON对象,我们就可以接收较小的JSON数据块流。 随着我们的NDJSON数据流入,我们可以立即开始处理和渲染。 这使用户感到高兴,因为他们能够更快地看到事物,而开发人员则感到高兴,因为它提高了整体性能。 如果将所有这些与服务人员联系在一起,那么您真的可以看到性能方面的改进 。
用法示例 (Example Usage)
As seen below, you can use fetch()
with an endpoint that sends NDJSON to start manipulating and rendering that data line-by-line as you receive it.
如下所示,您可以将fetch()
与发送NDJSON的端点一起使用,以在接收到数据时开始逐行处理和呈现该数据。
Sounds like a win-win, but what is the catch? Well, there are packages out there on npm such as ndjson that serializes JSON to NDJSON, but we don’t have an easy way to deserialize NDJSON to a stream of JavaScript objects… until now!
听起来像双赢,但有什么收获呢? 那么,有包在那里上NPM如ndjson序列化JSON来NDJSON,但我们没有一个简单的方法来反序列化NDJSON到JavaScript的一个流对象...到现在为止!
介绍can-ndjson-stream (Introducing can-ndjson-stream)
can-ndjson-stream is a simple JavaScript module that does the heavy lifting of serializing your NDJSON stream into a ReadableStream of JavaScript objects. Use this just as you would JSON.parse with a JSON object.
can-ndjson-stream是一个简单JavaScript模块,可以很轻松地将NDJSON流序列化为JavaScript对象的ReadableStream 。 就像使用JSON对象进行JSON.parse一样使用它。
Follow these simple steps to use the can-ndjson-stream
module.
请按照以下简单步骤使用can-ndjson-stream
模块。
//1. require the can-ndjson-stream module
import ndjsonStream from 'can-ndjson-stream';
//2. pass the NDJSON stream response body to the ndjsonStream function. Typically, this would be used with the fetch() method.
const readableStream = ndjsonStream(response.body);
//3. use readableStream, which is now a ReadableStream of JS objects, however you like. The ReadableStream API exposes a .getReader() and .cancel() method.
//https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream
入门 (Getting Started)
1.从npm下载该软件包并将其保存到您的项目中。 (1. Download the package from npm and save it to your project.)
npm i can-ndjson-stream --save
2.像在每个文件顶部的典型npm模块那样导入模块。 (2. Import the module as you would a typical npm module at the top of each file.)
Require var ndjsonStream = require('can-ndjson-stream');
要求var ndjsonStream = require('can-ndjson-stream');
-- OR --
- 要么 -
ES6 import import ndjsonStream from 'can-ndjson-stream';
ES6 import import ndjsonStream from 'can-ndjson-stream';
导入import ndjsonStream from 'can-ndjson-stream';
3.使用ndjsonStream
函数解析您的response.body
并处理结果。 (3. Parse your response.body
using the ndjsonStream
function and do work on the result.)
Once you parse your response.body
, you can interact with your ReadableStream by read
'ing it like this: exampleStream.getReader().read()
. That will return a promise that resolves to one line of your NDJSON.
一旦解析了response.body
,就可以通过read
与ReadableStream进行交互: exampleStream.getReader().read()
。 这将返回一个承诺,该承诺将解析为NDJSON的一行。
使用异步/等待 (Using Async/Await)
import ndjsonStream from 'can-ndjson-stream';
const fetchNdjson = async () => {
const response = await fetch("/api");
const exampleReader = ndjsonStream(response.body).getReader();
let result;
while (!result || !result.done) {
result = await exampleReader.read();
console.log(result.done, result.value); //result.value is one line of your NDJSON data
}
}
兑现承诺 (Using promises)
import ndjsonStream from 'can-ndjson-stream';
fetch('/api') // make a fetch request to a NDJSON stream service
.then((response) => {
return ndjsonStream(response.body); //ndjsonStream parses the response.body
}).then((exampleStream) => {
let read;
exampleStream.getReader().read().then(read = (result) => {
if (result.done) return;
console.log(result.value);
exampleStream.getReader().read().then(read); //recurse through the stream
});
});
4. [可选]创建一个简单的API来提供示例NDJSON数据。 (4. [Optional] Create a simple API to serve sample NDJSON data.)
Follow this tutorial on the Bitovi blog that gets you started or take a look at the demo in the can-ndjson-stream repo.
跟随Bitovi博客上的本教程开始学习,或查看can-ndjson-stream repo中的演示。
接下来是什么? (What next?)
If you enjoyed this article, tweet to us how you plan to use this module! Also check out the rest of the CanJS library. If you need any help, please don’t be afraid to leave a comment below or ask questions in the CanJS Gitter or forums!
如果您喜欢本文,请向我们发送推特,您打算如何使用此模块! 还要检查其余的CanJS库 。 如果您需要任何帮助,请不要害怕在下面发表评论或在CanJS Gitter或论坛中提问!
关于历史流的励志名言[^ 1] (Inspirational Quotes about Streams Through History[^1])
If not us, who? If not now, when? -- John F. Kennedy
如果不是我们,谁呢? 如果不是现在,那是什么时候? 约翰·肯尼迪
Hope is a waking stream. -- Aristotle
希望是清醒的溪流。 -亚里斯多德
Life is trying things to see if they work. -- Ray Bradbury
生活在尝试事物,看它们是否起作用。 -雷·布拉德伯里(Ray Bradbury)
[^1]: may or may not be accurate.
[^ 1]:可能准确也可能不准确。
[^2]: NDJSON stands for newline delimited JSON. Each newline character in a file separates that line into individual JSON objects enabling us to stream many smaller chunks of JSON rather than one large JSON object.
[^ 2]: NDJSON代表换行符分隔的JSON。 文件中的每个换行符都会将该行分成单独的JSON对象,使我们能够流式传输许多较小的JSON块,而不是一个大的JSON对象。
翻译自: https://davidwalsh.name/streaming-data-fetch-ndjson
fetch 文件流