web-dev-qa-db-ja.com

「チャンク」応答を時間内に受信して解析するためにクライアント側でJavaScriptを作成する方法は?

チャンクされた応答を生成するために、playフレームワークを使用しています。コードは次のとおりです。

class Test extends Controller {
    public static void chunk() throws InterruptedException {
        for (int i = 0; i < 10; i++) {
            String data = repeat("" + i, 1000);
            response.writeChunk(data);
            Thread.sleep(1000);
        }
    }
}

ブラウザを使用してhttp://localhost:9000/test/chunkにアクセスすると、表示されるデータが毎秒増加しているのがわかります。しかし、データを受信して​​処理するJavaScript関数を作成すると、すべてのデータが受信されるまでブロックされることがわかりました。

コードは次のとおりです。

$(function(){
    $.ajax(
        "/test/chunked", 
        {
            "success": function(data, textStatus, xhr) {
                alert(textStatus);
            }
        }
    );
});

すべてのデータを受信すると、10秒後にポップアップメッセージボックスが表示されます。

ストリームを取得して時間内にデータを処理する方法は?

37
Freewind

jQueryはそれをサポートしていませんが、単純なXHRでそれを行うことができます。

var xhr = new XMLHttpRequest()
xhr.open("GET", "/test/chunked", true)
xhr.onprogress = function () {
  console.log("PROGRESS:", xhr.responseText)
}
xhr.send()

これは、IE 10. W3C仕様 ここ を含む) すべての最新ブラウザ で機能します。

ここでの欠点はxhr.responseTextには累積応答が含まれます。部分文字列を使用できますが、 responseType 属性を使用し、sliceArrayBufferを使用することをお勧めします。

65
phil pirozhkov

まもなく、ReadableStream AP​​I( MDN docs here )を使用できるようになります。以下のコードはChromeバージョン62.0.3202.94で動作しているようです:

fetch(url).then(function (response) {
    let reader = response.body.getReader();
    let decoder = new TextDecoder();
    return readData();
    function readData() {
        return reader.read().then(function ({value, done}) {
            let newData = decoder.decode(value, {stream: !done});
            console.log(newData);
            if (done) {
                console.log('Stream complete');
                return;
            }
            return readData();
        });
    }
});
4
rinat.io

successイベントは、完全なデータ転送が完了し、接続が200応答コードで閉じられたときに発生します。ネイティブのonreadystatechangedイベントを実装して、データパケットが到着するのを確認できるはずです。

0
kishu27