获取与请求

时间:2016-08-03 04:25:57

标签: javascript node.js stream request fetch

我正在使用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.
*/

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

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

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或流功能。

2 个答案:

答案 0 :(得分:15)

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

获取流比XHR更具内存效率,因为完整响应不会在内存中缓冲,而result.valueUint8Array,这对二进制数据更有用。如果您需要文字,可以使用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块的格式。这很容易解析,并且在大多数工作中都依赖于浏览器的JSON解析器。 Here's a working demo,可以在较慢的连接速度下看到好处。

我还written an intro to web streams,其中包括他们在服务工作者中的使用。您可能还对使用JavaScript模板文字来创建streaming templates的有趣黑客感兴趣。

答案 1 :(得分:0)

原来我可以让XHR工作 - 这并没有真正回应请求与获取问题。经过几次尝试和正确的操作顺序才能做到正确。这是抽象的代码。 @jaromanda是对的。

var _tryXhr = function(target, data) {
  console.log(target, data);
  var xhr = new XMLHttpRequest();

  xhr.onreadystatechange = function () {
    console.log("state change.. state: "+ this.readyState);
    console.log(this.responseText);
    if (this.readyState === 4) {
      // gets hit on completion.
    }
    if (this.readyState === 3) {
       // gets hit on new event
    }
  };

  xhr.open("POST", target);
  xhr.setRequestHeader("cache-control", "no-cache");
  xhr.setRequestHeader("Content-Type", "application/json");
  xhr.send(data);   
};