2013-09-18 3 views
1

У меня есть функция для выполнения запросов Ajax с сервером. Код работает, но по какой-то причине блокирует остальную часть кода js. Поэтому я должен ждать, пока запрос не закончится. Это действительно странно, поскольку ajax является асинхронным по своей природе. Любая помощь будет оценена.Ajax Request блокирует

Вот код

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

и я называю эту функцию, как это вар Рез = initRequest ('someurl'); if (res) {console.log (res); } console.log («это сообщение появится, когда запрос будет подан! ПОЧЕМУ?»);

+3

[ 'XMLHttpRequest.open (метод, url [, async = true [, user = null [, password = null]]])] (http://www.w3.org/TR/XMLHttpRequest/#the-open%28%29- метод) – Andreas

ответ

1

Вы должны реализовать обратный вызов onreadystatechange в объекте XMLHttpRequest и проверить наличие там изменений статуса, вместо того, чтобы ждать блокировки для ответа вашего сервера. Этот метод будет вызван для каждого изменения свойства readyStatus и, надеюсь, вернет 200 в какой-то момент после вызова xmlhttp.send (...);

Edit: Так что ваш код будет выглядеть

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

+0

+1 для вашего ответа. –

0

Пожалуйста, измените запрос АЯКС от synchronous к 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); 
+0

Вы можете даже потерять третий параметр, так как по умолчанию этот флаг установлен на 'true'. Однако тогда вам понадобится реализовать метод onreadystatechange на объекте XHR, который отсутствует в этом ответе. – moxn

+0

Да, вы правы, отредактируйте его и спасибо. + 1 за ваше предложение. –

1

Третий параметр в 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); 

Позвольте мне знать, если это имеет смысл, или если у вас есть какие-либо вопросы :)

+0

Хорошо, спасибо, что сейчас это работает! Благодарю. –

+0

Рад, что он работает! Обязательно отметьте наиболее полезный вопрос в качестве ответа :) – asifrc

+1

@JabranSaeed вы также можете поддержать (один или несколько) ответы, которые были вам полезны. – moxn