Ajax太慢-递归 [英] Ajax too slow - Recursion

查看:63
本文介绍了Ajax太慢-递归的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我用来请求页面的Ajax代码占用了太多内存,并使浏览器变慢,并且一切都滞后了.似乎正在进行递归,我不知道有什么方法可以阻止它.代码如下所示.

A ajax code that i am using to request a page is consuming too much memory and is making the browser slow and everything lag. It seems like there is recursion going on and i dont know of any way to prevent it. Here is what the code looks like.

$(".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();
});

我该如何解决这个问题?预先感谢.

How can i solve this problem? Thanks in advance.

推荐答案

正在递归,并且您不应该使用这种形式的嵌套 setInterval .这样做会导致间隔实例爆炸.代替使用 setInterval ,而使用 setTimeout 安排其他请求.

You are recursing and you shouldn't be using this form of nested setInterval. Doing this, will cause an explosion of interval instances. Instead of using setInterval, schedule additional requests using setTimeout.

setInterval 将触发并继续触发每个间隔,直到您告知它停止为止.

setInterval will fire and continue firing every interval until you tell it to stop.

setTimeout 将触发一次.

setTimeout will fire once.

让我们考虑以下代码,该代码应解决您在此问题中遇到的一些问题以及其他两个问题.

Let's consider the following code which should address some of the issues you are having in this question as well as your other 2 questions.

首先,如我们之前所述,除非您确实希望它永久运行,否则请不要使用 setInterval .此外,除非确实需要,否则请勿嵌套创建 setInterval .

First off, as we said before, don't use setInterval unless you actually want it to run forever. Additionally, don't nest the setInterval creations unless you actually mean to.

相反,让我们创建一个递归函数 getTimeLeft(),该函数将处理触发请求并安排在一段时间后剩余时间的下一次检查.

Instead, let's create a recursive function getTimeLeft() that will handle firing the request and scheduling the next check for time left after some duration.

此示例还模拟了 $.ajax()函数,因为您没有实际使用的后端,因此您可以看到实际使用的函数.

This example also mocks the $.ajax() function so that you can see the function in action since we don't have an actual back end to use.

// 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非阻塞中遇到的问题,因为每个元素都有自己的元素提取剩余时间并自行更新的逻辑.

This code will address the issue that you are having in 2 Ajax non-blocking because each element will have it's own logic of going and fetching time left and updating itself.

这还解决了 Ajax中的计时器-抢占中可能面临的问题,因为现在该元素不再可用检查以查看在上一次检查完成之前还剩下多少时间.

This also addresses the issue that you are potentially facing in Timer in Ajax - Preemption because now the element won't check to see how much time is left again until after the previous check is finished.

这篇关于Ajax太慢-递归的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆