如何从jQuery中退出此递归轮询?

时间:2013-01-31 22:01:26

标签: javascript jquery ajax

我之前使用以下jQuery Ajax请求每3秒询问一次使用Ajax轮询的问题:

function getData() {
    $.ajax({
        url : 'http://example.com',
        type: 'GET',
        success : function(data) {
            // process data here
            setTimeout(getData, 3000);
        },
        dataType : 'json'
    });
}

似乎另一种方法是将setTimeout置于$ .ajax()块之外:

function getData() {
    setTimeout( function() {
    $.ajax({
        url : 'http://example.com',
        type: 'GET',
        success : function(data) {
            //process data here
        },
        dataType : 'json'
    }) }, 3000);
}

这两种方法之间有什么区别吗?它们是否具有每3秒连续轮询服务器的相同效果?

此外,在成功回调函数中,如果满足某些条件,如何终止此无限轮询,例如data.length> 1000然后我想终止此循环并调用另一个函数?我应该这样做:

function getData() {
        var tID = setTimeout( function() {
        $.ajax({
            url : 'http://example.com',
            type: 'GET',
            success : function(data) {
                //process data here
                if(data.length > 1000) { 
                   funcOutside();
                   clearTimeout(tID);
                }
            },
            dataType : 'json'
        }) }, 3000);
    }

3 个答案:

答案 0 :(得分:7)

第二个选项不会每3秒轮询一次;它只会轮询一次。

要有条件地继续或停止投票,您应使用第一个选项的变体:在setTimeout电话周围添加条件。

function getData() {
    $.ajax({
        url : 'http://example.com',
        type: 'GET',
        success : function(data) {
            // depending on the data, either call setTimeout or simply don't
            if( /* data says continue polling */) {
                setTimeout(getData, 3000);
            }
        },
        dataType : 'json'
    });
}

答案 1 :(得分:2)

  

这两种方法之间有什么区别吗?它们是否具有每3秒连续轮询服务器的相同效果?

是的,有一个重要的区别!第一个版本将在响应到达后将对函数的调用排队。因此,调用之间的间隔将是(大约)3000ms加上请求/响应所花费的时间。

第二个版本将在3秒后发出请求,然后停止。如果您将setTimeout更改为setInterval,它将每3秒发出一个新请求,但无法保证先前的请求在完成新请求时已经完成(如果一个请求需要〜 3000ms)。所以第一个版本可能正是你要找的。

关于终止循环:是的,只需添加类似于代码中的条件。但是不要清除超时,只是不要添加新的:

//process data here
if(data.length > 1000) { 
    funcOutside();
} else {
    setTimeout(getData, 3000);
}

最后注意事项:从技术上讲,这不是递归,因为它不是getData调用自身,而是来自setTimeout的回调始终调用getData

答案 2 :(得分:0)

(function loopsiloop(){
   setTimeout(function(){
   $.ajax({
       url: 'foo.htm',
       success: function( response ){
           // do something with the response

           loopsiloop(); // recurse
       },
       error: function(){
           // do some error handling.  you
           // should probably adjust the timeout
           // here.

           loopsiloop(); // recurse, if you'd like.
       }
   });
   }, 5000);
})();

这将为您完成工作。 我在这做三件事:

  1. 声明一个立即调用的函数loopsiloop(注意最后的parens)。
  2. 声明超时处理程序在5秒后触发。
  3. 在超时内轮询服务器,在成功/失败时将调用loopsiloop并继续轮询。