Ajax слишком медленный - рекурсия - PullRequest
0 голосов
/ 05 июня 2018

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

$(".item").each(function() {
    $this = $(this);
    var dataString = {s: "<?echo $_SESSION['currentview_'.$stamp]?>", r:"<?echo $search_usernumber?>", st: "<?echo $stamp?>"};
    $.ajaxSetup({cache:false});
    function timeLeft() {
        $.ajax({
            type: "POST",
            url: "get_content_home.php",
            dataType: "html",
            data: dataString, 
            success: function(result) {
                $this.html(result);
                //console.log("a");
                window.setInterval(function() {
                    timeLeft();
                }, 500);
            }
        });
    }
    timeLeft();
});

Как я могу решить эту проблему?Заранее спасибо.

1 Ответ

0 голосов
/ 05 июня 2018

Вы рекурсивны , и вам не следует использовать эту вложенную форму setInterval.Это приведет к взрыву интервальных экземпляров.Вместо использования setInterval, запланируйте дополнительные запросы, используя setTimeout.

setInterval будет срабатывать и продолжать стрельбу каждый интервал, пока вы не скажете ему остановиться.

setTimeout сработает один раз.


Давайте рассмотрим следующий код, который должен решить некоторые из проблем, которые возникают у вас в этом вопросе, а также 2 других вопроса.

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

Вместо этого давайте создадим рекурсивную функцию getTimeLeft(), которая будет обрабатывать запрос и планировать следующую проверку.на время, оставшееся после некоторой продолжительности.

В этом примере также выполняется имитация функции $.ajax(), чтобы вы могли увидеть функцию в действии, поскольку у нас нет фактического внутреннего интерфейса для использования.

// Fake server side data to keep track of time lefts
const timeLefts = {
  foo: 0,
  bar: 0,
  fizz: 0,
  buzz: 0
};
const timeLeftsUpdateInterval = setInterval(() => {
  for (const [key, val] of Object.entries(timeLefts)) {
    timeLefts[key] = Math.min(val + Math.random() * 10, 100);
  }
  if (Object.entries(timeLefts).every(([k, v]) => v >= 100)) {
    clearInterval(timeLeftsUpdateInterval);
  }
}, 1000);

// Mock $.ajax function to stub sending AJAX requests
function $ajax(kwargs) {
  return {
    done: cb => {
      setTimeout(() => {
        cb(timeLefts[kwargs.data.x]);
      }, 500);
    }
  };
}

// We will check for an update every second after the last request finishes
const timeLeftCheckInterval = 1000;

// Continuously check to see how much time is left for an element
function getTimeLeft(el) {
  // Make our request data
  const dataString = {
    s: "<?echo $_SESSION['currentview_'.$stamp]?>",
    r: "<?echo $search_usernumber?>",
    st: "<?echo $stamp?>",
    // My custom property to make this work
    x: el.dataset.item
  };

  // Make our request to get the time left
  const req = $ajax({ // Using our mock $.ajax
    type: "POST",
    url: "get_content_home.php",
    dataType: "html",
    data: dataString
  });

  // Once the request has finished
  req.done(data => {
    // Set the time left to the element
    el.innerHTML = data;

    // Have some condition so that you don't check for time left forever
    // Eventually there will be no time left right?  Why keep checking?
    if (data.timeleft <= 0) return;

    // Schedule another round of checking for time left after some duration
    setTimeout(() => {
      getTimeLeft(el);
    }, timeLeftCheckInterval);
  });
}

// Kick off getting timeleft for all .items
Array.from(document.querySelectorAll(".item"))
  .forEach(el => getTimeLeft(el));
<ul>
  <li class="item" data-item="foo"></li>
  <li class="item" data-item="bar"></li>
  <li class="item" data-item="fizz"></li>
  <li class="item" data-item="buzz"></li>
</ul>

Этот код решит проблему, с которой вы столкнулись в 2 неблокирующем Ajax , потому что каждый элемент будет иметь свою собственную логику переходаи выбор оставшегося времени и самообновление.

Это также решает проблему, с которой вы можете столкнуться в Таймер в Ajax - Preemption , потому что теперь элемент не будет проверять, сколько времениснова до окончания предыдущей проверки.

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