Как буферизовать Ajax-запрос? - PullRequest
0 голосов
/ 16 апреля 2009

У меня есть простая функция AJAX, что-то вроде этого:

var x;
var myRequest = new Array();

function CreateXmlHttpReq(handler) {
    var xmlhttp = null;
    try {
        xmlhttp = new XMLHttpRequest();
    }catch(e){
        try{
                xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
        }catch(e){
                xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
        }
    }
    xmlhttp.onreadystatechange = handler;
    return xmlhttp;
}

function getResults(){
    var r = Math.random();
    var someVar = document.getElementById('myvar').value;
    var myUrl = 'url/of/my/phpScript.php?';
    myUrl += 'r=' + r;
    //encodeURIComponent() instead of escape() when i aspect normal text
    myUrl += '&someVar=' + escape(someVar);
    //startLoading just show an overlay with a small rotating gif
    startLoading();
    x++;
    myRequest[x] = CreateXmlHttpReq(function() {printResultHandler(x)});
    myRequest[x].open("GET", myUrl);
    myRequest[x].send(null);
}

//example handler
function printResultHandler(x) {
    if(myRequest[x].readyState == 4 && myRequest[x].status == 200){
        //usually i use innerHTML for quick requests, the DOM for more complex req
        document.getElementById(div).innerHTML = myRequest[x].responseText;
        //this will hide the overlay showed ith startLoading()
        stopLoading();
    }
}
12345678901234567890123456789012345678901234567890123456789012345678901234567890

и это прекрасно работает. У меня просто есть некоторые проблемы, когда поток возврата велик (это может быть xml, html или что-то еще), браузер, кажется, «засыпает» на некоторое время. Мне не нравится иметь большое количество текста (xml, html) в одном. Это нехорошо с этим справляться.

Мне интересно, существует ли какой-нибудь способ для буферизации этого запроса. Когда запрос выполнен и возвращает статус 200, есть ли способ получить ответный текст по частям (скажем, 2048 байт или построчно)? Я полагаю, что-то вроде:

function printResultHandler(x) {
    if(myRequest[x].readyState == 4 && myRequest[x].status == 200){
        //usually i use innerHTML for quick requests, the DOM for more complex req
        //document.getElementById(div).innerHTML = myRequest[x].responseText;
        var answer;
        while(answer = readline(myRequest[x].responseText)){
            //to something;
        }
        //this will hide the overlay showed ith startLoading()
        stopLoading();
    }
}

Короче, эквивалент readdir () или fread () из php.

Ответы [ 3 ]

1 голос
/ 16 апреля 2009

Согласен, буферизация запроса - это не то, что вы можете сделать.

Вы можете подумать о том, чтобы распределить пользовательский запрос данных по набору HTTP-запросов, анализировать и обрабатывать каждый HTTP-запрос по мере его поступления.

Например, если пользователь хочет запросить записи с 1 по 1000, клиент может сначала запросить записи с 1 по 100, обработать, проанализировать и обработать их, затем запросить записи с 101 по 200 и так далее. Первые 100 записей будут отображаться относительно быстро, а через короткий период будут отображаться следующие 100 записей. Пока вторые 100 записей отображаются до того, как пользователю удалось обработать первые 100 записей, все должно быть в порядке. Общее время выполнения запроса будет больше, однако веб-приложение будет более отзывчивым, а предполагаемое время выполнения задачи будет меньше.

Вам следует также рассмотреть переход с XML на JSON, если вы не просто обновляете свойство innerHTML элемента данными.

Чтобы отобразить пользователю ответ на AJAX-запрос, ответ должен быть сначала проанализирован в структуре данных, а затем обработан. Удивительно, но время синтаксического анализа для XML и JSON практически одинаково. Разница заключается во времени, необходимом для прохождения и чтения полученной структуры данных.

Функции браузера для обхода и доступа к данным в DOM анализируемого ответа относительно медленны. Методы браузера DOM API маскируют сложность процесса обхода DOM и делают медленный процесс красивым и простым.

Доступ к данным в объектах JavaScript, возникающих в результате анализа ответа в формате JSON, выполняется намного быстрее. Обход объекта JavaScript легче в 2-3 раза быстрее, чем обход дерева DOM для того же набора данных.

В недавних тестах, проведенных с FireFox 3.1 beta 2 с использованием 10 МБ исходных данных, обход DOM ответа XML занял около 30 секунд. Выполнение того же для объекта JavaScript, заполненного тем же исходным большим набором данных, заняло около 15 секунд.

0 голосов
/ 16 апреля 2009

Вы должны сделать это вручную (он же код для себя).

Простое решение заключается в следующем (C = клиент, S = сервер)

  • C отправить запрос
  • S подготовить весь вывод
  • S генерирует некоторый ключ идентификатора данных (например, md5 данных)
  • S разбивает данные на куски и сохраняет их (и определяет их количество)
  • S возвращает идентификатор данных (и, возможно, счетчик чанков)
  • C выполняет итерацию от первого куска до последнего, отправляет серверу ключ данных (и номер чанка)
  • S возвращает запрошенный фрагмент
  • C отображает чанк (или содержимое загружает индикатор выполнения)

Предостережение заключается в том, что если вы идете не по индикатору выполнения, а вместо обработки instand, то S придется разрезать данные на куски как частично корректные фрагменты кода, которые могут обрабатываться с помощью C.

0 голосов
/ 16 апреля 2009

Нет, нет возможности буферизовать запрос. Если вы возвращаете огромное количество данных, а затем пытаетесь вставить их на страницу сразу, то анализ всего этого займет много времени.

Возможно, вы захотите подумать, есть ли другой способ получить желаемые результаты. Есть ли причина, по которой вам нужно вставить такой большой объем данных на страницу с помощью запроса AJAX?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...