weixin_33736832 2018-06-05 17:28 采纳率: 0%
浏览 50

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.

  • 写回答

1条回答 默认 最新

  • weixin_33698823 2018-06-05 17:39
    关注

    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 will fire and continue firing every interval until you tell it to stop.

    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.

    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.

    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.

    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>

    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.

    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.

    </div>
    
    评论

报告相同问题?

悬赏问题

  • ¥15 metadata提取的PDF元数据,如何转换为一个Excel
  • ¥15 关于arduino编程toCharArray()函数的使用
  • ¥100 vc++混合CEF采用CLR方式编译报错
  • ¥15 coze 的插件输入飞书多维表格 app_token 后一直显示错误,如何解决?
  • ¥15 vite+vue3+plyr播放本地public文件夹下视频无法加载
  • ¥15 c#逐行读取txt文本,但是每一行里面数据之间空格数量不同
  • ¥50 如何openEuler 22.03上安装配置drbd
  • ¥20 ING91680C BLE5.3 芯片怎么实现串口收发数据
  • ¥15 无线连接树莓派,无法执行update,如何解决?(相关搜索:软件下载)
  • ¥15 Windows11, backspace, enter, space键失灵