setInterval работает непрерывно в Firefox на Android

#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);