Javascript 如何从jQuery退出这个递归轮询?

Javascript 如何从jQuery退出这个递归轮询?,javascript,jquery,ajax,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);

我之前问过一个问题,使用以下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()块之外:

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

另外,在success回调函数中,如果满足某些条件,比如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秒轮询一次;它只会投票一次

要有条件地继续或停止轮询,您应该使用第一个选项的变体:在
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'
    });
}

第二个选项不会每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'
    });
}
那么这两种方法有什么区别吗?它们是否具有每3秒连续轮询服务器的相同效果

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

第二个版本将在3秒钟后发出请求,然后停止。如果将
setTimeout
更改为
setInterval
,它将每隔3秒发出一个新请求,但不能保证在发出新请求时(如果一个请求需要约3000毫秒),以前的请求已经完成。所以第一个版本可能就是你想要的

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

//process data here
if(data.length > 1000) { 
    funcOutside();
} else {
    setTimeout(getData, 3000);
}
最后一点注意:从技术上讲,这不是递归,因为它不是
getData
调用自身,而是
setTimeout
始终调用
getData
的回调

(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);
})();
那么这两种方法有什么区别吗?它们是否具有每3秒连续轮询服务器的相同效果

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

第二个版本将在3秒钟后发出请求,然后停止。如果将
setTimeout
更改为
setInterval
,它将每隔3秒发出一个新请求,但不能保证在发出新请求时(如果一个请求需要约3000毫秒),以前的请求已经完成。所以第一个版本可能就是你想要的

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

//process data here
if(data.length > 1000) { 
    funcOutside();
} else {
    setTimeout(getData, 3000);
}
最后一点注意:从技术上讲,这不是递归,因为它不是
getData
调用自身,而是
setTimeout
始终调用
getData
的回调

(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);
})();
这将为你做这项工作。 我在这里做三件事:

  • 声明一个立即被调用的函数loopsiloop(注意末尾的paren)
  • 声明在5秒后启动超时处理程序
  • 在超时时间内轮询服务器,成功/失败后将调用loopsiloop并继续轮询
  • 这将为你做这项工作。 我在这里做三件事:

  • 声明一个立即被调用的函数loopsiloop(注意末尾的paren)
  • 声明在5秒后启动超时处理程序
  • 在超时时间内轮询服务器,成功/失败后将调用loopsiloop并继续轮询

  • 谢谢你的建议。第二个版本实际上只轮询数据一次。我应该像你指出的那样使用第一个带有条件语句的语句。谢谢你的建议。第二个版本实际上只轮询数据一次。我应该像你指出的那样使用第一个带条件语句的语句。谢谢Jon。我认为你是对的。第二个版本只轮询一次。我会用你的方法做有条件停止投票。谢谢Jon。我认为你是对的。第二个版本只轮询一次。我将使用您的方法在轮询时执行条件停止。