1

我有一个使用服务器执行 Ajax 请求的功能。该代码有效,但由于某种原因阻止了其余的 js 代码。所以我必须等到请求结束。这真的很奇怪,因为 ajax 本质上是异步的。任何帮助将不胜感激。

这是代码

function initRequest(url)
{ 
    var xmlhttp = null;
    if(xmlhttp != null)
    { 
        if(xmlhttp.abort)
            xmlhttp.abort();
        xmlhttp = null; 
    };

    if(window.XMLHttpRequest) // good browsers 
        xmlhttp=new XMLHttpRequest(); 
    else if(window.ActiveXObject) // IE 
        xmlhttp=new ActiveXObject("Microsoft.XMLHTTP"); 

    if(xmlhttp == null)
        return null; 

    xmlhttp.open("GET",url,false); 
    xmlhttp.send(null); 

    if(xmlhttp.status >= 200 && xmlhttp.status < 300)// 2xx is good enough 
    return xmlhttp.responseText.split("|"); 
    else 
        return null; 
}

我像这样调用这个函数 var res = initRequest('someurl'); if(res) { console.log(res); } console.log('这个消息会在请求被处理的时候出现!!WHY??');

4

3 回答 3

3

您应该在 XMLHttpRequest 对象上实现 onreadystatechange 回调并检查其中的状态更改,而不是阻塞地等待服务器的响应。每次更改 readyStatus 属性时都会调用此方法,并且(希望)在调用 xmlhttp.send(...); 之后的某个时间点返回 200;

编辑:所以你的代码看起来像

function initRequest(url, onsuccess, onerror) { 
    // ...
    xmlhttp.onreadystatechange = function () {
        if(this.status >= 200 && this.status < 300) {// 2xx is good enough
            onsuccess(this.responseText.split("|"));
        }
    };
    xmlhttp.open("GET", url);  // its asynchronous by default
    xmlhttp.send(null); 
}

为了更好地衡量一些有用的链接 http://www.w3.org/TR/XMLHttpRequest1/https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest

于 2013-09-18T06:31:40.447 回答
1

in 第三个参数xmlhttp.open("GET",url,false);是是否异步发送请求。由于您输入了 false,它将同步运行,这就是它阻止您的代码的原因。

为了使这个异步,您应该将第三个参数更改为true,然后添加一个函数,xmlhttp.onreadystatechange该函数将作为异步请求的回调(在调用.send().

另一个需要考虑的重要事情是,由于这是异步的,你不想从你的 ajax 请求中返回一个值,因为你会有一些东西在等待那个返回值,这意味着它要么不会得到返回值,或者你必须阻止一切,我们又回到了原来的问题。所以考虑一下你想用 ajax 响应“做什么”。您可以直接将其编码到您分配给的任何内容中xmlhttp.onreadystatechange,或者您可以使用闭包将回调传递给它,例如

function initRequest(url, callback)
{ 
    ...
    xmlhttp.open("GET",url,true); 
    xmlhttp.onreadystatechange = (function(cb) {
        return function() {
            if(xmlhttp.status >= 200 && xmlhttp.status < 300)// 2xx is good enough 
            {
                cb(xmlhttp.responseText.split("|"));
            }
        };
    )(callback);
    xmlhttp.send(null); 
}

然后无论你在哪里调用initRequest,定义一个函数来处理结果,然后将它作为第二个参数传递,例如

var logResult = function(result) {
    console.log(result);
};

initRequest("page.php", logResult);

让我知道这是否有意义,或者如果您有任何问题:)

于 2013-09-18T06:50:34.130 回答
1

请将ajax 请求synchronousto更改为asynchronous并尝试,

从 ,

xmlhttp.open("GET",url,false); 

至 ,

xmlhttp.onreadystatechange = function () {
     if(this.status >= 200 && this.status < 300) {// 2xx is good enough

    }

}
xmlhttp.open("GET",url,true); 
于 2013-09-18T06:44:17.200 回答