2017-03-09 97 views
-1

我有一个div的jQuery集合。对于每个div我必须做两个ajax调用,而第一个调用返回一个由第二个调用使用的id。所有的Ajax调用都需要一些时间(比如说一秒钟)。定义几个Ajax调用的顺序

如果我做这样的事情:

$divs.each(function(index, element) { 
    $.get('/some/url').done(function (id) { 
     $.post('/some/other/url?id=' + id).done(function() { 
      $(element).doSomething(); 
     }); 
    }) 
}); 

那么所有得到通话将首先完成,然后将所有电话。但这并不是错误的,我希望尽早执行呼叫,以便尽早向用户显示第一个结果。

所以我不想:

get, get, get, get, get, get, get, get, post, post, post, post, post, post, ... 

,而这一点:

get, get, get, get, get, post, get, post, get, post, get, post, get, post, ... 

换句话说,只要对一个div第一次调用完成后,立即开始第二个电话。不要等到所有的第一个电话完成。

我想我必须排队打电话。我一定要吗?或者我怎么能做到这一点?

注意:浏览器只能并行执行有限数量的ajax调用。 Firefox中的AFAIK 6默认(Connections per Hostname)。$.get()调用可能很快,但连接限制会导致提取可能需要一些时间。 6个队列会有帮助吗?或者我应该为每个div有一个队列?

一个额外的任务将是取消整个处理,如果这也是可能的。

更新/解决方案:人们不明白我的问题是什么。正如一些人现在所建议的,我已经使用了priorityQueue in async库。有了这个,我可以减少未决连接的数量并控制请求的顺序。

+0

如果按照现在的方式进行操作,它确实是最快的。 (除非你能够将它们全部合并为一个)。否则,如果延迟了任何获取请求,用户将总体上必须等待更长的时间才能完成。 –

+0

@KevinB你是这么认为的吗?我看到整个处理时间不会改变。这只是一种重新排序,因此可以提前显示一些结果。 – robsch

+0

Gotcha。重新排序会使整体花费更长的时间,但由于前面提出了一些结果,因此会被认为更快。我建议先取第一个,比如说3,然后取其余的。 –

回答

0

嗨看看这个方法可以帮助你:

var divs = $("div"); 

recursiveFunction(divs); 

function recursiveFunction(divs){ 
    var element = divs.shift(); 
    $.get('/some/url').done(function (id) { 
    $.post('/some/other/url?id=' + id).done(function() { 
     $(element).doSomething(); 
     if(divs.length > 0){ 
      recursiveFunction(divs); 
     } 
    }); 
    }) 

} 

这样你可以有GET,POST,GET,POST。

+0

这将创建一个直接的调用序列,对吧?但我想尽可能使用并行执行(Firefox:可能有6个并行调用)。 – robsch

+0

你可以改变它来执行并行执行,你没看到这个吗? –

-1

$.get()方法异步返回。

这意味着,你是正确的,所有的$.get()旨意顺序执行,同步,他们每个人的然而回调函数(在.done()的内线回调)将被异步调用。

直到回调被调用所需的时间可能会有所不同,而执行$.get()的时间实际上为0,所以您现在的做法是好的。

0

我认为你的代码没有问题。只是你无法注意到触发事件。

在过去的异步调用更多的控制,你可以使用https://caolan.github.io/async/docs.html#controlflow

可以说你的每一个AJAX(get和post)调用发生在环路中的每个项目的1秒和处理需要几毫秒,10毫秒说。因此,对于5个格:

10ms 1st div 
-> get sent 

    20ms 2nd div 
    -> get sent 

    30ms 3rd div 
    -> get sent 

     40ms 4th div 
     -> get sent 

     50ms 5th div 
     -> get sent 

(总共50毫秒)所有的Ajax排队,但1日的div得到尚在处理,并会在1010ms和后REQ将被发送

现在,随着时间的进行后反应,下面会发生

(all get requests sent) 

    1010ms 1st div 
    -> post sent 

     1020ms 2nd div 
     -> post sent 

     1030ms 3rd div 
     -> post sent 

      1040ms 4th div 
      -> post sent 

      1050ms 5th div 
      -> post sent 

所以从上面的顺序是

get1, get2, get3, get4, get5, post1, post2, post3, post4, post5 

没有错。

+0

没有错,但不是最佳。看看这个问题的评论。 – robsch

+0

现在取决于网络延迟。当网络响应速度更快时,上述循环会更快。考虑你的请求在20ms内响应,那么订单将会与'get1,get2,post1,get3,post2,get4,post3,get5,post4,post5'不同。服务器和相同的应用程序,他们可以在单个AJAX调用中处理。 而我们在谈论优化时,为了初始化UI设置而发送如此多的AJAX请求并不好。 – Pankaj

+0

要优化,您可以一次请求5个ID,然后逐个处理POST请求或同时一次。 – Pankaj

0

你的代码没问题。你看到延迟的原因是因为你所有的get都被扔进了Javascript队列。有效地执行第一个获取,然后排队您的帖子请求,但是,还有其他获取您的帖子前面已经。

正如其他人指出的那样,网络延迟和处理获取/发布请求的服务器端时间会加剧此问题。根据用户体验来改进延迟问题的唯一真正解决方案是分块请求。基本上,队列x获得请求,比如说4,然后一旦这些请求完成或者使用settimeout并且猜测延迟或者通过事件触发后续请求,则加载x更多的请求。在我看来,后两者是不能很好地扩展的黑客。我建议使用第一个选项并下载异步js库,并使用parallel()方法排队前四个,并使用可选的回调启动下一批。冲洗并重复。