【问题标题】:How to get jquery to append output immediately after each ajax call in a loop如何让 jquery 在循环中的每个 ajax 调用后立即附加输出
【发布时间】:2013-11-10 23:05:28
【问题描述】:

我想附加到一个元素并让它立即更新。 console.log() 按预期显示数据,但 append() 在 for 循环完成之前什么都不做,然后一次全部写入。

index.html:

...
<body>
    <p>Page loaded.</p>
    <p>Data:</p>
    <div id="Data"></div>
</body>

test.js:

$(document).ready(function() {
    for( var i=0; i<5; i++ ) {
        $.ajax({
            async: false,
            url: 'server.php',
            success: function(r) {
                console.log(r); //this works
                $('#Data').append(r); //this happens all at once

            }
        });
    }
});

server.php:

<?php 
    sleep(1);
    echo time()."<br />";
?>

在 for 循环完成之前,页面甚至不会呈现。它不应该在运行 javascript 之前至少先渲染 HTML 吗?

【问题讨论】:

  • 你为什么用async: false

标签: javascript jquery html ajax loops


【解决方案1】:

如果您切换到async: true,那么屏幕将能够在您追加数据时更新。

$(document).ready(function() {
    var cntr = 0;
    // run 5 consecutive ajax calls
    // when the first one finishes, run the second one and so on
    function next() {
        $.ajax({
            async: true,
            url: 'server.php',
            success: function(r) {
                console.log(r); //this works
                $('#Data').append(r); //this happens all at once
                ++cntr;
                if (cntr < 5) {
                    next();
                }

            }
        });
    }
    next();
});

如果您坚持使用async: false(这通常很糟糕),那么您可以在每个 ajax 调用之间放置一个简短的setTimeout(),并且屏幕会在超时期间更新。

还有一些黑客“可能”通过访问某些 CSS 属性来更新屏幕(不保证)变化。我说“可能”是因为这不是规范,只是对某些浏览器中行为的观察。你可以阅读更多关于this option here的信息。

在任何情况下,由于您已经在使用 ajax 调用,因此在这里解决此问题的最佳方法是使用 async: true 并将您的循环构造更改为可以与异步 ajax 调用一起使用的循环构造(如我所示在我的例子中)。

【讨论】:

  • 谢谢!我想使用 async: false 因为我实际上正在做一些屏幕抓取并且不想猛击服务器。你能解释一下为什么循环需要像这样而不是简单的 for 循环吗?
  • 一个简单的for 循环结合async: true 将立即启动所有5 个ajax 调用,然后所有5 个结果都会进来。它将向服务器发送大量请求。按照我的方式发送一个,等待响应,当它得到第一个响应时,发送第二个,依此类推,而不是猛击服务器。所以,你可以使用我的方式来处理async: true,而不是猛击服务器。
  • 好吧,这是有道理的。感谢您的回答,这让我发疯了!我仍然不清楚为什么 for 循环和 async: false 不能达到同样的效果。是 jquery 还是浏览器(在本例中为 chrome)延迟了渲染?
  • @david_nash - 浏览器尝试将所有 DOM 更改合并为一个布局和一个重绘,因为这样执行得更好(重布局和重绘很慢)。因此,如果一个 JS 线程仍在运行,则浏览器在重新绘制屏幕之前正在等待它完成。当您使用async: false 时,JS 线程一直在运行且未完成,因此浏览器仍在等待您的最后一次 ajax 调用完成。不一定要那样,但它就是这样工作的。
猜你喜欢
  • 1970-01-01
  • 2011-03-15
  • 1970-01-01
  • 2021-10-08
  • 2016-07-21
  • 2013-11-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多