web-dev-qa-db-ja.com

フェッチとリクエスト

JSONストリームを使用していて、フェッチを使用して使用しようとしています。ストリームは数秒ごとにいくつかのデータを送信します。フェッチを使用してストリームを消費すると、ストリームがサーバー側を閉じたときにのみデータにアクセスできます。例えば:

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

ただし、すでにクライアントに送信されているデータのチャンクがいくつかあります。

browserでノードに触発されたメソッドを使用すると、イベントが送信されるたびに次のように機能します。

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またはストリーム機能を模倣できるはずだと言っています。

6
sparkFinder

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

これが上記の実例です

フェッチストリームは、完全な応答がメモリにバッファリングされないため、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が変換ストリームになり、response.body.pipeThrough(new TextDecoder())を実行できるようになります。これははるかに簡単で、ブラウザーが最適化できるようにします。

JSONの場合、ストリーミングJSONパーサーは少し大きくて複雑になる可能性があります。データソースを管理している場合は、改行で区切られたJSONのチャンクである形式を検討してください。これは本当に解析が簡単で、ほとんどの作業はブラウザーのJSONパーサーに依存しています。 これが動作するデモです 、接続速度が遅い場合に利点が見られます。

私も Webストリームの紹介を書いた 、これにはServiceWorker内からの使用が含まれます。 JavaScriptテンプレートリテラルを使用して ストリーミングテンプレート を作成する楽しいハックにも興味があるかもしれません。

17
JaffaTheCake

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