Ajax слишком медленный - Рекурсия

Ahsan Ahmed спросил: 12 мая 2018 в 03:48 в: javascript

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 ответ

Есть решение
zero298 ответил: 12 мая 2018 в 04:52

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

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

setTimeout будет запускаться один раз.


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

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

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

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

// 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 non-blocking , потому что у каждого элемента будет своя собственная логика перехода и выбор времени и само обновление.

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

Ahsan Ahmed ответил: 12 мая 2018 в 03:40
большое спасибо!