异步jQuery请求计时问题

时间:2009-09-11 16:54:14

标签: javascript jquery

作为一项学习练习,我已经将SO feature request的脚本混在一起(出于这个问题的目的,请忽略该请求的优点或其他内容)。在脚本中,我遇到了一个技术问题,即我的有限的javascript知识无法通过,我很感激有关如何解决它的建议。

为了避免向服务器发送垃圾邮件,我使用了一些搜索黑客来确定标记的答案数和接受的答案。这涉及使用window.setTimeout()回调函数,该函数为每个标记发送get请求,增加每次调用的超时以错开请求。

要在单个请求中获得结果,请将& pagesize = 1附加到get请求中url的末尾,以便结果中的页数为您提供结果总数,而无需进行任何操作进一步要求。

此方法的一个副作用是后续页面视图使用& pagesize = 1而我只看到一个条目。我尝试通过使用& pagesize = 30触发另一个查询来解决此问题,然后将其重置,但由于它是异步的,因此最后一次查询的时间可能导致页面大小为1或30,具体取决于哪个请求首先完成。我已尝试为此“重置”查询添加进一步的超时和回调,但它没有真正帮助。

是否有办法监控查询,等待所有查询完成,然后一旦完成所有发送重置请求?或者我可以采取另一种方法吗?

3 个答案:

答案 0 :(得分:5)

你可以建立一个调用链

基于my previous idea of a ParallelAjaxExecuter,这是一个SerialAjaxExecuter

$(function(){

  var se = new SerialAjaxExecuter( function( results )
  {
    console.log( results );
  }, 1000 );

  se.addRequest( $.get, 'test.php', {n:1}, function( d ){ console.log( '1 done', d ); }, 'text' );
  se.addRequest( $.get, 'test.php', {n:2}, function( d ){ console.log( '2 done', d ); }, 'text' );
  se.addRequest( $.get, 'test.php', {n:3}, function( d ){ console.log( '3 done', d ); }, 'text' );
  se.addRequest( $.get, 'test.php', {n:4}, function( d ){ console.log( '4 done', d ); }, 'text' );

  se.execute();

});

var SerialAjaxExecuter = function( onComplete, delay )
{
  this.requests = [];
  this.results  = [];
  this.delay    = delay || 1;
  this.onComplete = onComplete; 
}

SerialAjaxExecuter.prototype.addRequest = function( method, url, data, callback, format )
{
  var self = this;
  this.requests.push( {
      "method"    : method
    , "url"       : url
    , "data"      : data
    , "format"    : format
    , "callback"  : callback
  } );
  var numRequests = this.requests.length;
  if ( numRequests > 1 )
  {
    this.requests[numRequests-2].callback = function( nextRequest, completionCallback )
    {
      return function( data )
      {
        completionCallback( data );
        setTimeout( function(){ self.execute( nextRequest ); }, self.delay );
      }
    }( this.requests[numRequests-1], this.requests[numRequests-2].callback )
  }
}

SerialAjaxExecuter.prototype.execute = function( request )
{
  var self = this;
  if ( 'undefined' == typeof request )
  {
    request = this.requests[0];
    var lastRequest = this.requests[this.requests.length-1];
    lastRequest.callback = function( completionCallback )
    {
      return function( data  )
      {
          completionCallback( data )
          self.onComplete( self.results );
      }
    }( lastRequest.callback )
  }
  request.method( request.url, request.data, function( r )
  {
    return function( data )
    {
      self.results.push( data );
      r.callback( data );
    }
  }( request ) )
}

我没有在请求之间的休眠期间进行烘焙,但肯定可以添加。添加了超时

注意:此示例中充斥着您需要使用firebug的console.log()次调用,或者只是删除它们。

答案 1 :(得分:0)

我不确定我是否完全理解这个问题,但为什么不链接请求而不是使用setTimeout?所以在一个请求的响应处理程序结束时触发下一个请求。

答案 2 :(得分:0)

在页面上的每个链接上附加& pagesize =与您当前正在使用的页面大小一起使用。