【问题标题】:Simple AJAX seems to quietly overwhelm browser简单的 AJAX 似乎悄悄地压倒了浏览器
【发布时间】:2021-02-12 16:55:52
【问题描述】:

我有一个小的 AJAX,在一个递归函数中,还有一个在 complete 上的 setTimeout。由于我已经实现了这个,我有客户在页面上停留几个小时后抱怨延迟......

get_activity();

function get_activity() {
    var activity = $.ajax({
        type: "POST",
        url: "/ajax/activity.php",
        async: false
    }).complete(function () {
        setTimeout(function () {
            get_activity();
        }, 5000);
    }).responseText;

    $('#activity').html(activity);
}

因为它在回调中,.complete 并且它在 5 秒的 setTimeout 上,所以我认为运行它是安全的。响应只不过是一个正好有 1,000 行的表(基于mysql 调用中的LIMIT 和 3 列。没什么大不了的:

<table style="font-size:9px; width:100%; font-weight:bold; color:#FFF;">
<?php foreach ($activity_log as $item): ?>
    <tr>
        <td style="width:60px;">
            <?= $item['user'] ?>
        </td>
        <td style="width:120px;">
            <?= $item['activity'] ?>
        </td>
        <td style="width:100px;">
            <?= date('M j, Y G:i', strtotime($item['date_completed'])); ?>
       </td>
    </tr>
<?php endforeach; ?>
</table>

如果你注意到我正在使用我的 AJAX

$('#activity').html(activity);

$('#activity').append(activity);

所以$('#activity')s DOM 元素每次都会被覆盖。所以我知道我不会那样加载浏览器。

我觉得我做的一切都是正确的 -- 没有加载请求,有效地使它们同步 -- 而且我没有加载 DOM,而是用每个请求清除和填充 div

有没有人看到这个脚本及其响应会导致 Chrome 和 FF 在页面上几个小时后加载和滞后的原因?

【问题讨论】:

  • async: false
  • 不需要同步。将.html() 调用放入.complete() 函数中。
  • 锁定浏览器进行调用
  • 除此之外,AJAX 轮询在生产系统中是一个巨大的危险信号。如果您想让客户端与服务器数据保持同步,请考虑改用 Websockets,尤其是在有很多连接的客户端的情况下。您将网络流量和服务器负载减少一个数量级,从一开始就避免任何潜在问题,例如您遇到的问题。
  • @Zak - 是的,恐怕是的。它的作用是防止页面上发生任何事情。您不需要更多的东西来防止您的函数与自身重叠(假设您没有在其他任何地方调用get_activity),因为在前一个完成之前您不会开始下一个。

标签: javascript jquery ajax loops


【解决方案1】:

当心像这样不断地轮询。这通常是不好的做法。 This article 提供了一些替代方案。

但是对于你的 ajax 调用:

当您使用async: false 时,您使ajax 调用同步,这意味着当网络操作发生时,没有其他JavaScript 可以运行并且在大多数浏览器中,页面完全没有响应。

删除 async: false 并改用 success 回调:

function get_activity() {
    $.ajax({
        type: "POST",
        url: "/ajax/activity.php",
        // *** Use the `success` callback
        success: function(text) {
            $('#activity').html(text);
        },
        complete: function() {
            setTimeout(function () {
                get_activity();
            }, 5000);
        }
    });
}

【讨论】:

  • 糟糕,我忘了删除async: false。如果您在上面看到,请点击刷新。)
  • @Zak:您应该能够通过降低超时值来加速测试。最终结果应该是一样的。
  • 你应该考虑JSON输出 - 保存服务器和数据流,让客户端浏览器通过JS创建表,只需json_encode($activity_log)
  • 甚至没有花那么长时间 .. 马上就有明显的程序改进 .. 谢谢!
  • 后端开发人员仍然应该了解多线程与单线程;但可能没有意识到/不知道 javascript 是单线程的(一次只能做一件事,例如等待服务器请求)
猜你喜欢
  • 2015-11-26
  • 2016-01-14
  • 2012-01-23
  • 2015-02-14
  • 2019-02-17
  • 2018-03-26
  • 2019-11-22
  • 1970-01-01
  • 2014-07-03
相关资源
最近更新 更多