多个ajax请求,没有请求和响应冲突

Multiple ajax requests without requests and responses clashing

本文关键字:请求 求和 响应 冲突 ajax 多个      更新时间:2023-09-26

我一直遇到一个问题,我倾向于发送多个ajax请求来获取数据以刷新网页的不同组件。我总是使用我的自定义ajax函数(下面共享)来执行ajax调用。我发现这些要求有时会发生冲突。我还确保以两秒的间隔发送请求,希望它序列化我发送请求的方式。但我还是发现它有时会发生碰撞。我做错了什么?或者更确切地说,我可以对我的函数做些什么更改,以使它每次都能无缝地工作?

功能:

function get_xmlhttp_obj()
{
    try
    {
        // Firefox, Opera 8.0+, Safari
        xmlHttp = new XMLHttpRequest();
    }
    catch (e)
    {
        // Internet Explorer
        try
        {
            xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
        }
        catch (e) 
        {
            try
            {
                xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
            }
            catch (e)
            {
                alert(invalidbrowser);
            }
        }
    }
    return xmlHttp;
}
function passUrl(url1)
{    
    url1 = url1+"&sid="+Math.random();
    xmlHttp=get_xmlhttp_obj();
    xmlHttp.onreadystatechange = function() { stateChanged(xmlHttp); }; 
    xmlHttp.open("GET", url1, true);
    xmlHttp.send(null); 
}

function passposturl(url1,params)
{
    xmlHttp=get_xmlhttp_obj();
    xmlHttp.open("POST", url1, true);
    xmlHttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
    xmlHttp.setRequestHeader("Content-length", params.length);
    xmlHttp.setRequestHeader("Connection", "close");
    xmlHttp.onreadystatechange =  function() { stateChanged(xmlHttp); };        
    xml Http.send(params);  
}
function stateChanged(xmlHttp) 
{
    if (xmlHttp.readyState == 1 || xmlHttp.readyState == 2 || xmlHttp.readyState == 3 || xmlHttp.readyState == 0) 
    {
         // Wait state. I load loading text or image here
    }
    else if(xmlHttp.readyState == 4)
    {
         // catch the response and display in the specific container.
         if(loadflag=="global_live_xjournal_feed")
         {
           document.getElementById("global_live_xjournal_feed").innerHTML=xmlHttp.responseText;
           setTimeout("call_refresh_global_xjournal_feed", 5000);
         }
    }
} 

function call_refresh_global_xjournal_feed(obj)
{
    if(obj=="global_xjournal_feed")
    {
         var url = "ajax_activity_feed.php?id="+obj;
         passUrl(url);
         loadflag="global_live_xjournal_feed";
}
}

如果你想确保异步调用以串行方式执行,你可以始终使用回调中具有setTimeout()的递归异步调用。例如:

function DoSomething() {
   $.get('/ajax/call', function() {
      //do whatever
      setTimeout(DoSomething, 2000);
   }
}

在这个例子中,我使用jQuery的例子,但你可以很容易地切换你的函数$.get()。

这样,在第一个异步调用完成之前,您永远不会启动另一个异步调用。它可能比2秒长一点,但所有内容都将以串行方式运行。

按照您编写代码的方式,每个请求都使用不同的xmlHttp对象。没有碰撞,因为每个对象都有自己独立的状态。在处理结果时,您不必假设任何全局状态。只要您查看的是特定xmlHttp对象中的状态,为了知道该做什么而调用了该对象,就不会有问题。如果两个请求在同一时刻完成,一个将在另一个之前进入JS队列,它将运行它的statechange函数直到完成,然后第二个将获得它的statechange通知。

对于这样的异步调用,通常没有理由分散它们,除非在触发第二个调用之前需要第一个调用的结果。实际上,如果您立即启动两个请求,然后等待它们都完成,则可以获得更好的端到端性能。无论哪个先完成,你将获得它的statechange回调,然后第二个将在那之后进入。

仅供参考,如果您正在使用断点进行调试或查看调试控制台输出,则在解释输出时必须严格注意哪个xmlHttp对象是哪个对象,因为它们的进度的不同阶段可能会交错。

我的AJAX库将以两种可能的方式提供帮助:

1)库允许将多个调用"打包"到单个请求中,这样只有在所有调用完成时才调用处理程序。

2)另一种方法是使用单个调用者(HTTP对象)创建请求池。通常情况下,池会有多个调用者(允许多个同时请求)-但是将其限制为单个调用者将强制排队到该池的任何请求以串行方式运行。

我发现这个库在我的工作中非常有用,它可以在这里找到:

http://depressedpress.com/javascript-extensions/dp_ajax/