Как написать javascript на стороне клиента, чтобы получать и анализировать `chunked` ответ во времени? - PullRequest
34 голосов
/ 22 июля 2011

Я использую игровую среду, чтобы генерировать частичный ответ. Код:

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 секунд, когда все данные получены.

Как получить поток и вовремя обработать данные?

Ответы [ 3 ]

63 голосов
/ 05 сентября 2012

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 и использовать slice для ArrayBuffer.

4 голосов
/ 15 декабря 2017

Скоро мы сможем использовать ReadableStream API ( MDN документы здесь ). Код ниже, кажется, работает с 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();
        });
    }
});
0 голосов
/ 24 апреля 2012

Событие success сработает, когда будет завершена полная передача данных и соединение закрыто с кодом ответа 200. Я считаю, что вы должны иметь возможность реализовать собственное событие onreadystatechanged и видеть пакеты данных по мере их поступления.

...