小编典典

如何让jquery在循环中的每个ajax调用后立即追加输出

ajax

我想附加到一个元素并立即更新它。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吗?


阅读 343

收藏
2020-07-26

共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(通常太糟糕了),则可以setTimeout()在每个ajax调用之间放置一小段时间,并且屏幕将在超时期间更新。

还有一些黑客通过访问某些CSS属性“可能”导致屏幕更新(不保证),这些属性只能在HTML布局为最新时才计算,这可能导致浏览器显示最新更改。我之所以说“可能”,是因为这不是规范,而是对某些浏览器中行为的观察。您可以在此处阅读有关此选项的更多信息。

无论如何,由于您已经在使用ajax调用,因此解决此问题的最佳方法是使用async: true循环结构并将其更改为可用于异步ajax调用的结构(如我的示例所示)。

2020-07-26