定义几个Ajax调用的顺序
我有一个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库。有了这个,我可以减少未决连接的数量并控制请求的顺序。
嗨看看这个方法可以帮助你:
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。
这将创建一个直接的调用序列,对吧?但我想尽可能使用并行执行(Firefox:可能有6个并行调用)。 – robsch
你可以改变它来执行并行执行,你没看到这个吗? –
$.get()
方法异步返回。
这意味着,你是正确的,所有的$.get()
旨意顺序执行,同步,他们每个人的然而回调函数(在.done()
的内线回调)将被异步调用。
直到回调被调用所需的时间可能会有所不同,而执行$.get()
的时间实际上为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
没有错。
你的代码没问题。你看到延迟的原因是因为你所有的get都被扔进了Javascript队列。有效地执行第一个获取,然后排队您的帖子请求,但是,还有其他获取您的帖子前面已经。
正如其他人指出的那样,网络延迟和处理获取/发布请求的服务器端时间会加剧此问题。根据用户体验来改进延迟问题的唯一真正解决方案是分块请求。基本上,队列x获得请求,比如说4,然后一旦这些请求完成或者使用settimeout并且猜测延迟或者通过事件触发后续请求,则加载x更多的请求。在我看来,后两者是不能很好地扩展的黑客。我建议使用第一个选项并下载异步js库,并使用parallel()方法排队前四个,并使用可选的回调启动下一批。冲洗并重复。
如果按照现在的方式进行操作,它确实是最快的。 (除非你能够将它们全部合并为一个)。否则,如果延迟了任何获取请求,用户将总体上必须等待更长的时间才能完成。 –
@KevinB你是这么认为的吗?我看到整个处理时间不会改变。这只是一种重新排序,因此可以提前显示一些结果。 – robsch
Gotcha。重新排序会使整体花费更长的时间,但由于前面提出了一些结果,因此会被认为更快。我建议先取第一个,比如说3,然后取其余的。 –