定义几个ajax调用的顺序

时间:2017-03-09 15:40:25

标签: jquery ajax

我有一个带有一些div的jQuery集合。对于每个div,我必须做两个ajax调用,而第一个调用返回一个被第二个调用使用的id。所有ajax调用都需要一些时间(让我们说一秒钟)。

如果我这样做:

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

然后所有获取调用将首先完成,然后所有发布调用。这没有错,但是,我希望尽早执行 post 调用,以便更快地向用户显示第一个结果。

所以我不想要:

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库。有了这个,我可以减少挂起连接的数量并控制请求的顺序。

4 个答案:

答案 0 :(得分: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);
        }
     });
  })

}

这样你就可以获得,发布,获取,发布。

答案 1 :(得分:0)

我认为您的代码没有任何问题。只是你不能注意到触发事件。

要更好地控制异步调用,您可以使用https://caolan.github.io/async/docs.html#controlflow

让我们说你的每个ajax(get和post)调用需要1秒,并且循环中每个项目的处理需要几毫秒,比如说10ms。所以对于5个div:

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排队,但第一个div的获取仍在处理中,并将在1010ms上回复,之后将发送请求

现在随着时间的推移,将会发生以下事件

(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

没有错。

答案 2 :(得分:0)

你的代码很好。您看到延迟的原因是因为您的所有获取都被抛入Javascript队列。有效地执行第一次获取然后排队您的帖子请求,但是,您的帖子前面还有其他信息。

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

答案 3 :(得分:-1)

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

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

调用回调所花费的时间可能会有所不同,而$.get()执行的时间几乎为0,所以你现在这样做的方式很好。