如何在没有网页冻结的情况下同步调用ajax

时间:2010-11-04 16:25:17

标签: jquery ajax webpage freeze

我有一些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);  
  }
});
  });
});

6 个答案:

答案 0 :(得分:15)

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

答案 1 :(得分:3)

如果您不希望您的呼叫是异步的,则浏览器无法更新将冻结的UI。为什么你不能让它异步?而不是一次完成所有100,只需等待一个完成,然后调用下一个。

答案 2 :(得分:1)

你需要重构这个东西。 100个ajax请求是疯了,所有这些请求都是同步的。

我建议你重构你的应用程序,这样你就可以解析所有数据并将其发送到一个异步请求或几个异步请求中,而不是100个。

如果您需要100,请创建某种队列并按顺序异步处理它们。

答案 3 :(得分:0)

问题就在于Ajax ...代表“异步JavaScript和XML”......

尝试同步执行Ajax会破坏使用Ajax的目的。

尝试使用线程池并将其运行为异步。

答案 4 :(得分:0)

编辑 - 正确答案

大多数浏览器会限制对单个服务器的HTTP请求数量,可能是为了防止您尝试阻止(服务器过载)的情况。我不确定现代浏览器的实际数字是多少,但我认为它不仅仅是我在2005年在Firefox中观察到的旧“2”。

一些资源:

旧答案

此脚本每2秒调用一次同步$.ajax,每次都将数据移出数组a。在每个请求实际执行期间,UI仍将锁定,但允许它在调用之间自行更新。我认为,这是完全同步和完全异步之间非常好的折衷。

请注意,此脚本具有破坏性 - 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);
});

答案 5 :(得分:-1)

我遇到了类似的问题,我需要同步调用,而IE却冻结了。总之,我提出了这种方法。

  1. 我使用async:true。
  2. 而不是使用synchroniou调用
  3. 在complete:function中递归调用下一个ajax请求。
  4. 这让我能够同步拨打同步电话,所以我在上一次通话后打电话。