2010-02-22 2 views
2

Я использую глобальные переменные для передачи вокруг ответа от вызова AJAX:AJAX: Ожидание ответа?

window.response = null; // most recent response from XMLHttpRequest 

// the callback function for XMLHttpRequest 
function userObjFromJSON() { 
    if (this.readyState == 4) { 
     var json = eval('(' + this.responseText + ')'); 
     window.response = json; 
    } 
    else { 
     indicateLoading(); 
    } 
} 

// loads the info for this username on the page 
function loadUsernameInfo(username) { 
    clearPage(); 
    getUserInfo(username); 
    var profile = window.response; // most recent json response (what if it hasn't come in yet?) 
    window.response = null; 
    if (profile) { 
     indicateLoaded(username); 
     fillInProfileInfo(profile); 

     getTweets(username); 
     var tweets = window.response; // most recent json response (what if it hasn't come in yet?) 
     if (tweets) { 
      fillInTweets(tweets, MAX_TWEETS); 
      var mentions = mentionedUsers(tweets, MAX_TWEETS); 
      fillInMentioned(mentions); 
     } 
     else { 
      indicateUnavailableTweets(); 
     } 
    } 
    else { 
     indicateInvalidUsername(username); 
    } 
} 

Проблема заключается в том, что к тому времени, функция контроллера хочет начать заполнение информации, вызов AJAX не всегда вернулся еще. (Если я медленно прохожу через него в отладчике, он отлично работает.) Что я могу сделать, чтобы обойти это?

Я пытался что-то вроде этого:

getUserInfo(username); 
while (window.response == null); // infinite loop here 
var profile = window.response; // most recent json response 

Но это только делает мой браузер не отвечает.

Я не решаюсь вызывать нужную функцию из обратного вызова, потому что я пытаюсь реализовать модель-view-controller. Вызов функции контроллера/просмотра из модели кажется, что она нарушит шаблон.

ответ

2

Лучшей практикой здесь было бы разместить код, который у вас есть в настоящее время в loadUsernameInfo, в обратном вызове для самого вызова AJAX, вместо того, чтобы полагаться на глобальную переменную. Таким образом, когда ваш ответ вернется, обратный вызов, который выполняется вместо того, чтобы просто установить вашу переменную window.response, действительно продолжит работу и обновит ваш пользовательский интерфейс и выполнит любые другие связанные задачи.

Другой способ сделать то же самое, просто позвонить loadUsernameInfo из существующей функции обратного вызова, как:

// the callback function for XMLHttpRequest 
function userObjFromJSON() { 
    if (this.readyState == 4) { 
     var profile = eval('(' + this.responseText + ')'); 
     loadUsernameInfo(username, profile); 
    } 
    else { 
     indicateLoading(); 
    } 
} 

Надежда, что помогает!

0
function userObjFromJSON() { 
if (this.readyState == 4) { 
    var json = eval('(' + this.responseText + ')'); 
    window.response = json; 
// why dont you call needed function here ? 
} 
else { 
    indicateLoading(); 
} 

}

Почему бы вам не позвонить всю необходимую функцию при установке window.response?

В худшем случае вы можете использовать window.setTimeout для ожидания ответа ajax, но лучший способ - использовать события.

0

Ваш XMLHttpRequest должен использовать событие onreadystatechange. например:

var xmlHttp=new XMLHttpRequest(); 
xmlHttp.onreadystatechange=function(){ 
    if(xmlHttp.readyState!=4 || (xmlHttp.status!=200 && xmlHttp.status!=304))return; 
    callback(xmlHttp.responseText); 

} 

Где callback() - это функция, которую вы хотите вызвать. Готовое состояние 4 означает, что содержимое закончило загрузку. И две записи состояния должны убедиться, что URL-адрес не дал ошибку.

+0

Я пытаюсь сделать модель-view-controller, и помещение вызова функции там нарушит это. –

Смежные вопросы