获取与请求

spa*_*der 6 javascript stream request fetch node.js

我正在使用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.
*/
Run Code Online (Sandbox Code Playgroud)

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

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

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)
 }));
Run Code Online (Sandbox Code Playgroud)

我错过了什么?我的直觉告诉我,fetch应该能够模仿pipe 或流功能.

Jaf*_*ake 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!');
  });
});
Run Code Online (Sandbox Code Playgroud)

这是上面的一个工作示例.

取流是多个存储器效率比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!');
  });
});
Run Code Online (Sandbox Code Playgroud)

这是上面的一个工作示例.

很快TextDecoder就会变成一个变换流,允许你做response.body.pipeThrough(new TextDecoder()),这更简单,并允许浏览器进行优化.

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

我还写了一个关于网络流的介绍,其中包括他们在服务工作者中的使用.您可能还对使用JavaScript模板文字创建流模板的有趣hack感兴趣.