2010-11-04 188 views
2

我有一些JavaScript可以触发大约100次对php脚本的调用。 php脚本占用大量内存并需要几秒钟才能完成,然后返回一个json响应通过或失败。如何在没有我的网页冻结的情况下同步调用ajax

我不希望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); 
    } 
}); 
    }); 
}); 
+14

...你在做什么需要100个Ajax请求? – 2010-11-04 16:28:30

回答

14

你可以把在执行下一次调用的函数,并从您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个电话,除非这是一个测试套件,否则我会重新访问整个方法。

+2

注意:如果您从ajax回调的执行上下文中发出Ajax请求,IE6将会窒息。在setTimeout()中调用nextCall()调用以避免该问题(如果您的目标是IE6兼容性)。 – 2010-12-24 04:15:25

+0

@Nick:我需要100多个电话。建议的解决方案 – 2016-03-15 09:31:23

3

如果你不希望你的调用是异步的,那么浏览器将无法更新将冻结的UI。为什么你不能使它异步?不要一次完成100个,只需等待一个完成,然后再拨打下一个。

+0

这样做的最佳方式是什么? – Paul 2010-11-04 16:28:30

+0

set i = 0;然后用[i]作为参数调用,然后在完成时(使用成功函数),递增i并再次调用它。当我== a.length,你完成了。 – 2010-11-04 16:30:02

0

很好用,问题是,阿贾克斯......代表“异步JavaScript和XML” ......

试图做阿贾克斯同步失败摆在首位使用Ajax的目的。

尝试使用线程池并运行它异步。

1

你需要重构这件事。 100个Ajax请求是疯狂的,它们都是同步的。

我建议你重构你的应用程序,所以您可以分析所有数据并发送一个异步走,或一对夫妇异步请求,而不是100。

如果你需要100,使某种队列和异步按顺序处理它们。

+0

我假设他无法在一次通话中全部通话,因为他想在每个请求之间更新ui。但是,如果他可以在一个请求中完成所有工作,那就打个电话。 – 2010-11-04 16:32:39

0

编辑 - 正确答案

大多数浏览器将HTTP请求的数量限制在一台服务器,大概是为了防止情况就像你正试图阻止(服务器过载)。我不确定现代浏览器的实际数据是什么,尽管我认为它比2005年在Firefox中观察到的旧“2”还要多。

一些资源:

老回答

该脚本将每2秒钟调用一次同步$.ajax,每次将数据从数组a中移出。在每个请求实际执行期间,用户界面仍然会锁定,但会允许它在两次调用之间自行更新。我认为,这是在完全同步和完全异步之间的一个很好的妥协。

请注意,此脚本具有破坏性 - 完成后,a将为空。如果您需要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); 
}); 
-1

我有类似的问题,我需要同步调用和IE浏览器冻结。总之我想出了这种方法。

  1. 而不是使用synchroniou调用我用async:true。
  2. 在完成:函数中递归调用next ajax请求。

它允许我不同寻常地呼叫同步呼叫,所以我在先前的呼叫之后呼叫。

+2

此解决方案在此问题的接受答案中提供。请在提供您自己的解决方案之前阅读现有的解决方案,因为这样可以避免重复,而是在问题中添加其他信息。对于那些非常古老的问题,尤其如此,因为社区可能已经无数次地回顾了Q&A,因此很少有任何可以改进的问题。哦,顺便说一句,欢迎来到StackOverflow! – bPratik 2012-09-22 18:50:30

相关问题