如何在没有网页冻结的情况下同步调用ajax
我有一些javascript,可以触发大约100个调用php脚本。 php脚本占用大量内存并需要几秒钟才能完成,然后返回json响应pass或fail。
我不希望ajax调用是异步的,因为服务器会停止运行100个自身的实例,所以我尝试使用同步,唯一的问题是它冻结网页,而它一次调用脚本一个调用。
如何一次启动一个ajax调用而不冻结我正在使用的页面?
var a = []; a[0] = 'test'; a[1] = 'hello'; a[2] = 'another'; $(document).ready(function(){ $.each(a, function(k,v) { $.ajax({ url:'/this-script-takes-a-few-seconds-to-complete.php', async:false, data: {foo: v}, success: function(data){ console.log(data); } }); }); });
你可以输入一个执行下一个调用的函数,并从success
处理程序中调用它,如下所示:
$(function(){ var i = 0; function nextCall() { if(i == a.length) return; //last call was last item in the array $.ajax({ url:'/this-script-takes-a-few-seconds-to-complete.php', data: { foo: a[i++] }, success: function(data){ console.log(data); nextCall(); } }); } nextCall(); });
虽然……更好的方法是不要拨打100个电话,除非这是一个类型的测试套件,我会重新访问整个方法。
如果您不希望您的调用是异步的,则浏览器无法更新将冻结的UI。 为什么你不能让它异步? 而不是一次完成所有100,只需等待一个完成,然后调用下一个。
你需要重构这个东西。 100个ajax请求是疯了,所有这些请求都是同步的。
我建议您重构您的应用程序,以便您可以解析所有数据并将其发送到一个异步请求,或一些异步请求,而不是100。
如果您需要100,请创建某种队列并按顺序异步处理它们。
那么问题就是Ajax …代表“异步JavaScript和XML”……
尝试同步执行Ajax会破坏使用Ajax的目的。
尝试使用线程池并运行它async。
编辑 – 正确答案
大多数浏览器会限制对单个服务器的HTTP请求数量,可能是为了防止您尝试阻止(服务器过载)的情况。 我不确定现代浏览器的实际数字是多少,但我认为它不仅仅是我在2005年在Firefox中观察到的旧“2”。
一些资源:
- 在Firefox中,默认值似乎是15:check
about:config
,并查找max-connections-per-server
- IE似乎因连接类型和版本而异: http : //msdn.microsoft.com/en-us/library/cc304129(VS.85).aspx
- Chrome似乎是6: http : //www.google.com/support/forum/p/Chrome/thread?tid = 2218bcd015cdc0cc&hl = zh-CN
老答案
该脚本每2秒调用一次同步$.ajax
,每次都将数据移出arraysa
。 在每个请求实际执行期间,UI仍将锁定,但允许它在调用之间自行更新。 我认为,这是完全同步和完全异步之间的相当好的折衷。
请注意,此脚本具有破坏性 – 完成后将为空。 如果您需要a的内容,则可能需要创建副本。
a = [ 'test', 'hello', 'another' ]; $(function() { var send = function() { $.ajax({ url: '/this-script-takes-a-few-seconds-to-complete.php', async: false, data: {foo: a.shift()}, success: function(data) { console.log(data) } }); if (!a.length) { clearInterval(timer); } } var timer = setInterval(send, 2000); });
我有类似的问题,我需要同步调用和IE冻结。总之我想出了这个方法。
- 而不是使用synchroniou调用我使用async:true。
- 在complete:function中递归调用next ajax request。
它允许我同步拨打同步电话,所以我在上一次通话后打电话。