获取与请求 [英] Fetch vs Request

查看:70
本文介绍了获取与请求的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用JSON流,并尝试使用fetch来使用它。流每隔几秒发出一些数据。使用fetch来使用流只允许我在流关闭服务器端时访问数据。例如:

I'm consuming a JSON stream and am trying to use fetch to consume it. The stream emits some data every few seconds. Using fetch to consume the stream gives me access to the data only when the stream closes server side. For example:

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.
*/

但是,已经有几个数据块已经发送到客户端。

However, there have been several chunks of data already sent to the client.

浏览器中使用节点启发式方法就像每次发送一个事件一样有效:

Using a node inspired method in the browser like this works every single time an event is sent:

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应该能够模仿管道或流功能。

What am I missing? My instinct tells me that fetch should be able to mimic the pipe or stream functionality.

推荐答案

response.body 允许您以流的形式访问响应。要读取流:

response.body gives you access to the response as a stream. To read a stream:

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!');
  });
});

< a href =http://jsbin.com/depifa/edit?js,console =noreferrer>以下是上述的工作示例。

获取流比XHR更具内存效率,因为完整响应不在内存中缓冲,而 result.value Uint8Array 使其对二进制数据更有用。如果你想要文字,你可以使用 TextDecoder

Fetch streams are more memory-efficient than XHR, as the full response doesn't buffer in memory, and result.value is a Uint8Array making it way more useful for binary data. If you want text, you can use 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!');
  });
});

以下是上述的工作示例。

很快 TextDecoder 将成为转换流,允许您执行 response.body.pipeThrough(new TextDecoder()),这更简单,并允许浏览器优化。

Soon TextDecoder will become a transform stream, allowing you to do response.body.pipeThrough(new TextDecoder()), which is much simpler and allows the browser to optimise.

至于你的JSON案例,流式JSON解析器可能有点大而复杂。如果您控制数据源,请考虑由换行符分隔的JSON块的格式。这很容易解析,并且在大多数工作中都依赖于浏览器的JSON解析器。 这是一个工作演示,可以在较慢的连接速度下看到好处。

As for your JSON case, streaming JSON parsers can be a little big and complicated. If you're in control of the data source, consider a format that's chunks of JSON separated by newlines. This is really easy to parse, and leans on the browser's JSON parser for most of the work. Here's a working demo, the benefits can be seen at slower connection speeds.

我还撰写网络流介绍 ,包括他们在服务工作者中的使用。您可能还对使用JavaScript模板文字创建流媒体模板的有趣黑客感兴趣。

I've also written an intro to web streams, which includes their use from within a service worker. You may also be interested in a fun hack that uses JavaScript template literals to create streaming templates.

这篇关于获取与请求的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆