2012-07-05 126 views
0

因此情况如下:jQuery:暂停或延迟功能

我有一个递归的,异步的AJAX调用,它正在从服务器拉数据。这个递归调用在用户登录时只发生一次。 我有另一个需要AJAX调用才能导航的页面(基本上是一个延迟加载的树)。当第一个AJAX调用正在发生时,这些其他调用需要一段时间才能完成,并且由于第一个调用可能发出多达2000个请求,所以此延迟有时会相当长。

基本上我想实现的是在进行其他调用时“暂停”递归调用。伪代码:

function recursiveAjax(){  
    $.ajax({ 
     async : true, 
     url : 'someurl', 
     dataType : 'json', 
     beforeSend : function(xhr) { 
      // do stuff 
     }, 
     error : function(xhr, ajaxOptions, thrownError) { 
      // handle errors 
     }, 
     success : function(data) { 
      //conditions 
      recursiveAjax(); 
     } 
    }); 
} 

function navigationAjax(){  
    $.ajax({ 
     async : true, 
     url : 'someurl', 
     dataType : 'json', 
     beforeSend : function(xhr) { 
      // pause recursiveAjax(); 
     }, 
     error : function(xhr, ajaxOptions, thrownError) { 
      // handle errors 
     }, 
     success : function(data) { 
      //conditions 
      // resume recursiveAjax(); 
     } 
    }); 
} 
+0

这非常疯狂。尝试在超时块中包装递归调用,例如成功:setTimeout(function(){recursiveAjax();},500); - 这应该为其他呼叫留出空间,并且不那么疯狂。 – Mahn 2012-07-05 13:26:01

+0

看看[jQuery deferreds](http://api.jquery.com/category/deferred-object/) – elclanrs 2012-07-05 13:27:13

回答

1

由于您可能不希望同时发生这两个请求,因此让递归方法可以执行一个或另一个。当你想导航呼叫设置一个标志,让递归方法做到这一点的请求下一次迭代:

var navigationCall = false; 

function recursiveAjax(){ 
    if (navigationCall) { 
    navigationCall = false; 
    $.ajax({ 
     async : true, 
     url : 'someurl', 
     dataType : 'json', 
     error : function(xhr, ajaxOptions, thrownError) { 
     // handle errors 
     }, 
     success : function(data) { 
     //conditions 
     recursiveAjax(); 
     } 
    }); 
    } else { 
    $.ajax({ 
     async : true, 
     url : 'someurl', 
     dataType : 'json', 
     beforeSend : function(xhr) { 
     // do stuff 
     }, 
     error : function(xhr, ajaxOptions, thrownError) { 
     // handle errors 
     }, 
     success : function(data) { 
     //conditions 
     recursiveAjax(); 
     } 
    }); 
    } 
} 

function navigationAjax(){ 
    navigationCall = true; 
} 

注意:您可能想添加一个window.TimeOut呼叫做递归限制请求的流服务器。与人眼可以看到更改相比,更经常地调用服务器毫无意义。

+0

递归调用在后台构建数据树 - 用户永远不会看到它。如果这棵树不需要存在,它会使我的生活变得更容易,但是它确实存在,并且每次都需要这样做。谢天谢地,这只是一个临时措施,但看到我的应用程序表现如此糟糕,仍然让我感到很痛苦。 – Squishy 2012-07-05 13:54:41

+0

而且工作正常。仍然是一个非常沉重的表现,但它的速度是以前的两倍,所以至少有这种情况。非常感谢 – Squishy 2012-07-05 14:05:49

+0

为什么不限制recursiveAjax()的速率;火灾?每500毫秒运行一次可能会在性能方面产生巨大差异。 – Mahn 2012-07-05 18:52:00

2

最简单的方法:

window.recurse = true; 
function recursiveAjax(){  
    $.ajax({ 
     async : true, 
     url : 'someurl', 
     dataType : 'json', 
     beforeSend : function(xhr) { 
      // do stuff 
     }, 
     error : function(xhr, ajaxOptions, thrownError) { 
      // handle errors 
     }, 
     success : function(data) { 
      //conditions 
      if(window.recurse){ 
       recursiveAjax(); 
      } 
     } 
    }); 
} 

function navigationAjax(){  
    window.recurse=false; 
    $.ajax({ 
     async : true, 
     url : 'someurl', 
     dataType : 'json', 
     beforeSend : function(xhr) { 
      // pause recursiveAjax(); 
     }, 
     error : function(xhr, ajaxOptions, thrownError) { 
      // handle errors 
     }, 
     success : function(data) { 
      //conditions 
      window.recurse=true; 
      recursiveAjax(); 
     } 
    }); 
} 
+0

很好的答案,但它并没有明显的性能差异。 navigationAjax调用仍然延迟几秒钟。 – Squishy 2012-07-05 13:51:49

+0

@Squishy:你不会看到任何性能差异,唯一的区别是你不让客户端代码发出另一个递归请求,而​​不是让服务器队列发出请求。但是,在等待递归请求的响应时,您仍在执行导航请求,因此导航请求仍将由服务器排队。 – Guffa 2012-07-05 14:02:27

1

JavaScript是一种异步的语言,所以你可以做这样想你想只有像其他评论回调(见上文)。但考虑一下你的问题,大多数情况下最好在Web上使用异步。你真的想要这个吗?

+0

不,我不知道 - 但是我的老板呢。就像我刚才提到的那样,它是一个临时性的措施,至少这个代码不会在野外长期存在。 – Squishy 2012-07-05 14:07:00