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

时间:2011-07-19 00:03:27

标签: javascript ajax

我一直遇到多个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";
}
}

3 个答案:

答案 0 :(得分:1)

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

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

在这个例子中,我使用的是jQuery示例,但您可以使用$ .get()轻松切换功能。

这样,在完成第一个异步调用之前,您永远不会启动另一个异步调用。它可能会超过2秒,但一切都会串行运行。

答案 1 :(得分:1)

您拥有代码的方式,每个请求都使用不同的xmlHttp对象。没有碰撞,因为每个对象都有自己独立的状态。处理结果时,您不必假设任何全局状态。只要您正在查看的是特定xmlHttp对象中的状态,该对象已被调用以便知道该怎么做,您应该没问题。如果两个请求在完全相同的时刻完成,则一个将在另一个之前进入JS队列,它将运行它的状态转换函数完成,然后第二个将获得它的状态转换通知。

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

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

答案 2 :(得分:0)

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

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

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

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

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

希望这有帮助。