XmlHttpRequest возвращает состояние 4 слишком рано
Я разрабатываю код JavaScript для запуска на встроенном устройстве с помощью браузера ANT Galio.
В идеале я хотел бы, чтобы код отправлял запрос на получение на другой сервер. После того, как этот запрос get сделан, страница не позволит пользователю отправить другой запрос get, пока не будет получен ответ от предыдущего запроса get.
Почему-то иногда я получаю ReadyState 4 почти мгновенно. Как будто он оценивает предыдущий объект XmlHttpRequest, а не новый. Что я делаю неправильно?
<script type="text/javascript">
var fail= function (env, resp, stat) {
alert(resp);
};
var succ= function (env, resp) {
};
var canScan = true;
/* start scan */
function scan (name) {
if (canScan) {
//deactivate button
deactivateScanButtons();
//let server know
ajax = new XMLHttpRequest();
var scanUrl = 'http://19X.1XX.X.XX:8080/scan/' + name
ajax.open('GET', scanUrl, true);
ajax.onreadystatechange = function() {
if (ajax.readyState==4) {
//allow button to work again
activateScanButtons();
alert("ready state 4");
};
};
ajax.send();
//initiate scan
xrxScanInitiateScan(
'http://127.0.0.1',
"ftp.xst",
false,
succ,
fail);
}
}
function deactivateScanButtons () {
// canScan = false;
var indicator = document.getElementById('buttons');
indicator.style.visibility = "hidden";
}
function activateScanButtons () {
// canScan = true;
var indicator = document.getElementById('buttons');
indicator.style.visibility = "visible";
}
</script>
2 ответа
3 предложения:
- Чтобы избежать кэширования на стороне клиента, добавьте случайно сгенерированное число или текущую временную метку в строку запроса.
- Как сказал Йони, начни свой
XMLHttpRequest
объект сvar
ключевое слово. - Для каждого запроса сохраняйте текущую метку времени в глобальной переменной. В
onreadystatechange
, вызовactivateScanButtons
только если глобальная временная метка совпадает с соответствующей временной меткой данного запроса. Таким образом, только последний запрос сможет позвонитьactivateScanButtons
,
Вы определяете объект AJAX в scan
функция без var
Ключевое слово перед этим. Это означает, что это глобальный объект, а не локальный. После этого у вас есть замыкание - вы ссылаетесь на эту переменную в onreadystate
функция обратного вызова.
Мне трудно точно отслеживать, что там происходит, но я согласен с вами, как вы сказали в своем вопросе, что обратный вызов не использует объект ajax так, как вы ожидаете. Вы говорите, что это случается иногда - это происходит, когда вы делаете два запроса почти одновременно (дважды щелкните кнопку или иным образом быстро вызовете два запроса get)?
Я предлагаю вам использовать var
Ключевое слово перед определением объекта AJAX. Еще лучше, попробуйте использовать this
в функции обратного вызова вместо ссылки на объект AJAX по имени. Если это работает, вы избавили себя от одного закрытия.