每秒执行一个Ajax请求

20

我有一个ajax调用正在访问一个php文件。我已经收到结果。现在我正在调查是否可能使ajax请求每1秒自动执行一次。我将结果发布到名为hidden的输入字段中。如何在不调用该函数的情况下每三秒执行一次ajax调用?

    $.ajax({
            type: 'POST',
            url: 'increment.php',
            data: $(this).serialize(),
            dataType: 'json',
            success: function (data) {
                    $('#hidden').val(data);// first set the value     

            }
    });

5
每秒执行一个Ajax请求。不,不要这样做 :-) - T.J. Crowder
@T.J.Crowder 我知道这不是好的实践。只是为了学习而已。 - Code_Ed_Student
3个回答

51

您可以使用一系列重复的 setTimeout 调用来实现此操作。(不要ajax 调用与 setInterval 结合使用,否则很快就会陷入混乱;即使上一个 ajax 调用尚未完成,setInterval 也会触发下一个 ajax 调用。)

使用 setTimeout 来安排第一次调用,然后在它完成后安排下一个调用,以此类推:

var interval = 1000;  // 1000 = 1 second, 3000 = 3 seconds
function doAjax() {
    $.ajax({
            type: 'POST',
            url: 'increment.php',
            data: $(this).serialize(),
            dataType: 'json',
            success: function (data) {
                    $('#hidden').val(data);// first set the value     
            },
            complete: function (data) {
                    // Schedule the next
                    setTimeout(doAjax, interval);
            }
    });
}
setTimeout(doAjax, interval);

请注意,我正在使用complete而不是success来安排下一次调用,这样中断(例如您的网络连接暂时断开)就不会结束进程。


2
现在更明白为什么要使用 setTimeout 而不是 setInterval - Code_Ed_Student
你能否将complete替换为always,因为旧的已经被弃用了? - Dharman
1
@Dharman - 你让我有一瞬间的担忧,我想“他们肯定不会废弃那个吧?!”而且他们没有。上面使用的complete选项并未被废弃。jqXHR对象上的complete 方法(未在上面使用)已被废弃。 :-) - T.J. Crowder

15

你可能想考虑的是Server Sent Events(SSE)。

这是一项HTML5技术,其中Javascript会“长轮询”服务器端点(您的PHP文件)以查看是否发生了任何更改。长轮询基本上是JS(我不确定它是否使用Ajax或另一种技术)每秒向端点发送请求。

您可以尝试以下方式:

#/your_js
var evtSource = new EventSource("increment.php");
evtSource.onmessage = function(e) {
    $('#hidden').val(e.data);
}

要发送数据,您可以进行ajax调用,此操作将向服务器发送更新后的JSON对象,就像您所拥有的:

  $(document).on("click", ".your_object", function(data) {
     $.ajax({
                type: 'POST',
                url: 'increment.php',
                data: $(this).serialize(),
                dataType: 'json'
        });
   });

当您执行某个事件时,这将仅打开一个Ajax请求,并且您的应用程序将每秒“侦听”响应。如您所知,Ajax长轮询非常耗费资源,因此如果您想要真正的“实时”技术,最好查看WebSocket相关内容,但无论如何,这将比仅使用普通的Ajax更为高效

需要注意的是-- 您将需要更改increment.php以处理不同的响应类型


如果您对此感兴趣,我可以详细说明。 - Richard Peck
非常好,我之前并不知道这个。我一直在检查表中当前行数的 increment.php 文件。我会进一步了解这个。 - Code_Ed_Student
+1 很有趣,有一个 HTML5 的解决方案。 - Praveen
当我们尝试在其中一个应用程序中创建一些实时通知时,我使用了SSE。一开始感觉像是走在雷区,但实际上这很容易做,特别是如果您正在使用框架。如果没有,部署仍然相当简单。 - Richard Peck
1
非常有趣,但截至 Can I use,IE/Edge 仍不支持它。 - DaviG

7

可以使用setInterval实现。

1) 将ajax放在一个函数中。

function fun() {
$.ajax({
            type: 'POST',
            url: 'increment.php',
            data: $(this).serialize(),
            dataType: 'json',
            success: function (data) {
                    $('#hidden').val(data);// first set the value     

            }
    });
}

2) 现在通过使用 setInterval,您可以每秒执行一次它。

var interval = setInterval(fun, 1000);

3) 暂停/清除使用 clearInterval

clearInterval(interval);

4) 其他人指出,使用setInterval来处理ajax不明智,建议尝试使用

var interval;
function callAjax() {
  $.ajax({
                type: 'POST',
                url: 'increment.php',
                data: $(this).serialize(),
                dataType: 'json',
                success: function (data) {
                        $('#hidden').val(data);// first set the value 
                        interval = setTimeout(callAjax, 1000);   
                }
        });
}
callAjax();
//clearTimeout(interval);

2
真的,不过我更喜欢使用 setTimeoutclearTimeout,这样即使服务器在执行后端时有点慢,也不会出现重叠请求的情况。 - h2ooooooo
在使用 ajax 时,一定要使用重复的 setTimeout(在前一个完成后安排下一个)而不是 setInterval。使用 setInterval 和 ajax 请求会导致混乱。 - T.J. Crowder
1
你的 setTimeout 示例会导致该函数被调用两次。 - T.J. Crowder
@T.J.Crowder 对不起,我的错。我已经纠正了它。但是因为让我们知道了complete回调函数,所以加上+1。非常明智的解决方案。谢谢。 - Praveen
如果你在匿名函数内设置interval,那么你可能不需要设置它。要么在全局作用域声明变量,要么根本不需要声明。另外,正确的写法是clearTimeout(interval)而不是clearTimeout(fun) - h2ooooooo
@h2ooooooo 错过了。谢谢你指出我的错误。 - Praveen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接