#javascript #ajax #firefox #fennec
#javascript #ajax #firefox #fennec
Вопрос:
У меня есть короткий фрагмент Javascript, который я хочу опрашивать сервер каждые пару секунд и обновлять DOM.
function updateCard() {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 amp;amp; this.status == 200) {
card = JSON.parse(this.responseText);
document.getElementById("season").innerHTML = card.season;
}
};
xhttp.open("GET", "/curr_card/", true);
xhttp.send();
}
window.onload = updateCard;
window.setInterval(updateCard,2000);
В большинстве браузеров именно это и происходит. Есть несколько разовых вызовов updateCard
, но в целом сервер показывает ~ 1/2 соединения в секунду на каждого клиента.
Однако, когда я захожу на страницу в Firefox на Android (49.0), браузер начинает непрерывно опрашивать /curr_card/
, десятки раз в секунду.
Я видел, как люди предлагали заменить строку setInterval на window.setInterval(function() {updateCard();},2000);
, это не помогает.
Я довольно новичок в Javascript и AJAX, поэтому понятия не имею, почему это происходит. Это ошибка в FF? Я могу опубликовать больше кода, если потребуется.
Заранее спасибо.
Комментарии:
1. Я не знаю ни о каких ошибках. Вы пробовали использовать
window.setTimeout()
? Если это работает, вы можете просто установить таймер в концеupdateCard()
, который повторно вызывает себя снова…2. Это хорошая идея, чтобы вернуться к @Dario, но проблема в том, что это, возможно, не займет ровно 2 секунды (если это важно). Джиппо, он постоянно опрашивает десятки раз в секунду в самом начале или только через некоторое время? Кроме того, можно ли с уверенностью предположить, что этого не происходит в Chrome на Android?
3. Я не могу поставить рекурсивный setTimeout, поскольку функция также вызывается из другого места. Но я создал рекурсивную оболочку:
function continuousUpdate() { updateCard(); window.setTimeout(continuousUpdate,2000); } window.onload = continuousUpdate;
У этого та же проблема. Я не вижу проблемы в Chrome на Android.4. Я там. Как дела с вашей стороны?
5. Еще раз спасибо за вашу помощь
Ответ №1:
После тестирования и обсуждения в комментариях OP мы пришли к выводу, что это должно быть проблемой, специфичной для Firefox на HTC M7 от OP, поскольку ее невозможно воспроизвести в той же версии Firefox на Galaxy S7.
Ответ №2:
Это может произойти не только с Firefox на каком-либо устройстве.
Это может произойти, когда ответ не завершен из-за позднего ответа сервера, но он отправляет другой запрос и так далее…
Что, если сделать так:
function updateCard(before, after) {
if(before) {
before();
}
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 amp;amp; this.status == 200) {
card = JSON.parse(this.responseText);
document.getElementById("season").innerHTML = card.season;
}
if(after) {
after();
}
};
xhttp.open("GET", "/curr_card/", true);
xhttp.send();
}
window.onload = updateCard;
var updateCardRunning = false;
setInterval(function() {
if(updateCardRunning === true) {
console.log('postponing to next schedule');
return;
}
updateCard(
function() {updateCardRunning = true;},
function() {updateCardRunning = false;}
);
}, 2000);
или:
function updateCard() {
var xhttp = new XMLHttpRequest();
window.xhttp = xhttp;
xhttp.onreadystatechange = function() {
if (this.readyState == 4 amp;amp; this.status == 200) {
card = JSON.parse(this.responseText);
document.getElementById("season").innerHTML = card.season;
}
};
xhttp.open("GET", "/curr_card/", true);
xhttp.send();
}
window.onload = updateCard;
setInterval(function() {
if(window.xhttp) {
window.xhttp.abort();
}
updateCard();
}, 2000);