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
またはストリーム機能を模倣できるはずだと言っています。
_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テンプレートリテラルを使用して ストリーミングテンプレート を作成する楽しいハックにも興味があるかもしれません。
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);
};