Как в процессе JavaScript необработанный, но часть XMLHttpRequest responseText только в обработчике onprogress / onreadystatechange, без использования глобальных переменных для XMLHttpRequest, prevDataLength, nextreadPos и inProgress (для блокировки)?
Проблема заключается в следующем: я хочу обновить веб-страницу на основе полученной в настоящее время части данных, полученных с использованием AJAX (текущее значение responseText XMLHttprequest). Я хочу обновить страницу, как только сервер отправит данные (это так называемый шаблон потоковой передачи HTTP). Когда я выполняю обновление, я хочу обработать только еще необработанную часть responseText.
Дополнительная сложность заключается в том, что responseText может содержать незаконченный фрагмент ответа; с этим легко справиться (как и я), используя терминаторы; тогда вы можете легко извлечь полные ответы.
В настоящее время я использую глобальные переменные и блокировку, чтобы избежать проблемы с вызовом обработчика, когда предыдущий вызов не завершился (обработка новых данных). Мой код выглядит (упрощенно) следующим образом:
function processData(unprocessed, nextReadPos) {
var lastLineEnd = unprocessed.lastIndexOf('\n');
if (lastLineEnd !== -1) {
var lines = unprocessed.substring(0, lastLineEnd).split('\n');
nextReadPos += lastLineEnd + 1 /* 1 == '\n'.length */;
processLines(lines);
} // end if
return nextReadPos;
}
function handleResponse() {
...
// here xhr.readyState === 4 && xhr.status === 200
// in case we were called before finished processing
if (inProgress) {
return;
} else {
inProgress = true;
}
// extract new whole (complete) lines, and process them
while (prevDataLength !== xhr.responseText.length) {
if (xhr.readyState === 4 &&
prevDataLength === xhr.responseText.length) {
break;
}
prevDataLength = xhr.responseText.length;
var unprocessed = xhr.responseText.substring(nextReadPos);
nextReadPos = processData(unprocessed, nextReadPos);
} // end while
...
inProgress = false;
}
...
xhr.onreadystatechange = handleResponse;
Если бы у меня был более простой обработчик, я мог бы защитить от повторного ввода обработчика, когда он не завершил работу, передав объект XMLHttpRequest в качестве параметра, например, например случай 1 в разделе «Шаг 3 - простой пример» статьи AJAX / Getting_Started на Центр разработчиков Mozilla:
httpRequest.onreadystatechange = function() { alertContents(httpRequest); }; //1 (simultaneous request)
который в обозначениях, используемых в более крупном фрагменте кода, имеет вид
xhr.onreadystatechange = function() { handleResponse(xhr); }; //1 (simultaneous request)
Но этот пример не говорит мне, что делать с другими глобальными переменными: prevDataLength и nextReadPos. Они используются для определения наличия новых данных и для извлечения полных «предложений» из ответа сервера соответственно.
Как это сделать без глобальных переменных?