如何同步调用ajax而不让我的网页冻结

问题描述 投票:0回答:7

我有一些 javascript,可以触发大约 100 次对 php 脚本的调用。 php 脚本占用大量内存,需要几秒钟才能完成,然后返回通过或失败的 json 响应。

我不希望 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);  
  }
});
  });
});
jquery ajax html freeze
7个回答
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 次调用,除非这是某种测试套件,但我会重新访问整个方法。


3
投票

如果您不希望调用异步,那么浏览器将无法更新 UI,从而会冻结。为什么不能让它异步?不要一次执行所有 100 项操作,只需等待其中一项完成,然后调用下一项即可。


1
投票

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

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

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


0
投票

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

尝试同步执行 Ajax 就违背了使用 Ajax 的初衷。

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


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);
});

0
投票

对“async: false”ajax 调用使用“setTimeout”。

setTimeout(function () {
        // ajax calls here
    },
    250
);

-1
投票

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

  1. 我没有使用同步调用,而是使用了 async:true。
  2. 在complete:function中递归调用下一个ajax请求。

它允许我异步调用同步调用,所以我在上一个调用之后调用。

© www.soinside.com 2019 - 2024. All rights reserved.