获取vs请求

我在使用JSONstream,并试图使用fetch来使用它。 该stream每隔几秒发射一些数据。 只有在streamclosures服务器端时,使用fetch来使用stream才能访问数据。 例如:

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

我错过了什么? 我的本能告诉我,抓取应该能够模仿pipe或streamfunction。

response.body使您可以访问作为stream的响应。 读取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!'); }); }); 

以上是一个有效的例子 。

提取stream比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!'); }); }); 

以上是一个有效的例子 。

不久, TextDecoder将成为一个转换stream,允许你做response.body.pipeThrough(new TextDecoder()) ,这是非常简单的,并允许浏览器优化。

至于你的JSON情况,streamJSONparsing器可能有点大而复杂。 如果您控制的是数据源,请考虑使用换行符分隔的JSON块。 这很容易parsing,并且依靠浏览器的JSONparsing器进行大部分工作。 这是一个工作演示 ,在连接速度较慢时可以看到好处。

我还写了一个networkingstream的介绍 ,其中包括他们在服务工作者的使用。 您也可能对使用JavaScript模板文字创buildstream模板的有趣黑客感兴趣。

原来,我可以让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); };