我正在使用 JSON 流并尝试使用 fetch 来使用它。流每隔几秒发出一些数据。只有当流关闭服务器端时,使用 fetch 来使用流才能让我访问数据。例如:
var target; // the url.
var options = {
method: "POST",
body: bodyString,
}
var drain = function(response) {
// hit only when the stream is killed server side.
// response.body is always undefined. Can't use the reader it provides.
return response.text(); // or response.json();
};
var listenStream = fetch(target, options).then(drain).then(console.log).catch(console.log);
/*
returns a data to the console log with a 200 code only when the server stream has been killed.
*/
但是,已经有几 block 数据发送给了客户端。
每次发送事件时,在浏览器中使用 Node 启发方法都有效:
var request = require('request');
var JSONStream = require('JSONStream');
var es = require('event-stream');
request(options)
.pipe(JSONStream.parse('*'))
.pipe(es.map(function(message) { // Pipe catches each fully formed message.
console.log(message)
}));
我错过了什么?我的直觉告诉我,fetch 应该能够模仿 pipe
或流功能。
最佳答案
response.body
使您能够以流的形式访问响应。读取流:
fetch(url).then(response => {
const reader = response.body.getReader();
reader.read().then(function process(result) {
if (result.done) return;
console.log(`Received a ${result.value.length} byte chunk of data`);
return reader.read().then(process);
}).then(() => {
console.log('All done!');
});
});
Here's a working example of the above .
Fetch 流比 XHR 更节省内存,因为完整的响应不会缓冲在内存中,而且 result.value
是一个 Uint8Array
使其更有用对于二进制数据。如果你想要文本,你可以使用 TextDecoder
:
fetch(url).then(response => {
const reader = response.body.getReader();
const decoder = new TextDecoder();
reader.read().then(function process(result) {
if (result.done) return;
const text = decoder.decode(result.value, {stream: true});
console.log(text);
return reader.read().then(process);
}).then(() => {
console.log('All done!');
});
});
Here's a working example of the above .
很快 TextDecoder
将成为一个转换流,允许您执行 response.body.pipeThrough(new TextDecoder())
,这更简单并且允许浏览器优化。
至于您的 JSON 案例,流式 JSON 解析器可能有点庞大和复杂。如果您可以控制数据源,请考虑使用换行符分隔的 JSON block 格式。这真的很容易解析,大部分工作都依赖于浏览器的 JSON 解析器。 Here's a working demo ,可以在较慢的连接速度下看到好处。
我也written an intro to web streams ,其中包括它们在 service worker 中的使用。您可能还对使用 JavaScript 模板文字创建 streaming templates 的有趣技巧感兴趣。 .
关于javascript - 获取与请求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38734400/