我有一个带有一些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();
});
})
});
然后,所有 get 呼叫将首先完成,然后将所有 post 调用。但是,这并不是错的,我希望尽早执行 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, ...
换句话说:第一次呼叫完成后,立即开始第二个呼叫。不要等到所有第一个电话都完成。
我认为我必须以某种方式排队电话。我一定要吗?还是我该怎么做?
注意:浏览器仅在并行执行有限量的AJAX呼叫。默认情况下,Firefox中的Afaik 6(每个主机名)。 $.get()
调用可能很快,但是连接限制导致提取可能需要一些时间。6个队列会有所帮助吗?还是我应该为每个div有一个队列?
如果可能的话,一个额外的任务是取消整个处理。
更新/解决方案:人们不了解我的问题是什么。正如某些人现在推荐的那样,我在异步库中使用了优先级。这样,我可以减少待处理的连接数量并控制请求的顺序。
嗨,查看此方法是否可以帮助您:
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);
}
});
})
}
这样,您可以得到,发布,获取,发布。
我认为您的代码没有错。只是您无法注意到触发事件。
要进行更多控制异步调用,您可以使用https://caolan.github.io/async/docs.html#controlflow
可以说,您的每个ajax(获取和发布)呼叫需要1秒,而循环中每个项目的处理需要几毫秒,例如10ms。因此,对于5个divs:
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
(总计50ms)所有ajax排队,但是第一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
没有错。
您的代码很好。您看到延迟的原因是因为您所有的东西都被扔进了JavaScript队列。有效地,第一个获取将执行,然后排队您的帖子请求,但是,您的帖子已经在您的帖子前面。
正如其他人指出的那样,网络延迟和服务器端处理get/post请求的时间将加剧这一点。从用户的体验中改善延迟问题的唯一真正解决方案是使请求减少。基本上,排队x获取请求,例如4,然后加载x一旦完成或使用settimeout并使用settimeout并通过事件触发后续请求。在我看来,后两个是无法缩放的黑客。我建议使用第一个选项并下载async js库,并使用Parallel()方法排队前四个,并使用可选回调开始下一批。冲洗并重复。
$.get()
方法异步返回。
这意味着您是正确的,所有$.get()
s将被顺序执行,同步执行,,但是 每个中的回调函数(.done()
s中的回调)将异步称为异步。
呼叫回调的时间可能会有所不同,而执行$.get()
s的时间实际上是0,因此您现在这样做的方式很好。