同步AJAX调用不是真正的同步

时间:2012-03-07 19:52:53

标签: javascript ajax

我遇到了同步AJAX请求的问题。

我正在创建一个Web应用程序,其中有许多AJAX请求按顺序调用,应按严格顺序返回。我决定只是同步调用它们,而不是将每个后续请求放在最后一个请求的readystatechange事件处理程序中。

但是,在以下代码中,在将响应添加到DOM之前,会调用alert()

window.addEventListener("load", main, false);

function main (e) {

    // Sending synchronous request
    var request = new XMLHttpRequest();
        request.open("GET", fileName, false);
        request.overrideMimeType("text/xml");
        request.send(null);

    // Receiving response
    var response = request.responseXML;

    // Changing XML Tree to corresponding XHTML Tree
    response = XMLtoXHTML(response);

    //Adding response to the body
    document.body.appendChild(response);

    // Calling alert
    alert("Hello World");

}

响应实际上已成功添加到DOM ,但仅在警报消息上单击“确定”后才会显示。当我使用Safari的脚本调试功能进行演练时,在调用alert()之前,响应 会添加到DOM

有什么建议吗?

注意:我遗漏了其他请求。

3 个答案:

答案 0 :(得分:3)

我猜它确实会被添加,你只是在JS将控制权返回给浏览器之前没有看到更改,即直到警报窗口关闭。如果你不能做异步请求(我先建议),你至少可以在一个单独的setTimeout ed“线程”中进行dom更改。

答案 1 :(得分:2)

它确实被添加到DOM中,但页面尚未将新元素解析为视图。如果我不得不猜测,自从警报阻止当前正在运行的JS线程webkit尝试在此期间执行回流以提高效率。

测试用例:

function foo()
{
   var div = document.createElement("div");
   div.innerHTML = "hi friends";
   div.id = "bar";
   document.body.appendChild(div);
   alert(document.getElementById("bar").innerHTML);
}

您是否需要在警报出现之前显示该元素?在这种情况下使用

setTimeout(function(){alert("Hello World");}, 1);

答案 2 :(得分:0)

或者使用像Frame.js(或asnyc,flow.js,更多)这样的流量控制库:

Frame(function(next)){ 
    document.body.appendChild(response);
    next();
});
Frame(function(next)){ 
    alert("Hello World");
    next();
});
Frame.init();