2013-07-11 5 views
0

Я новичок в программировании на JavaScript. Я просто не могу найти ответ, который работает.Дождитесь, пока метод async приложения завершит javascript

Проблема заключается в том, что моя функция работает только тогда, когда он обернут в SetTimeout вызов следующим образом:

var sPageIdentifier = 'ReportViewer'; 
UserPreferencesManager.Initialize(sPageIdentifier); 
setTimeout(function() { 
var strUserPrefs = UserPreferencesManager.GetPreferences(); 
    console.log(strUserPrefs); 
    initLayout(strUserPrefs); 
}, 1000); 

function initLayout(strUserPrefs) { 
    //do stuff using strUserPrefs 
} 

Если я закомментировать функцию SetTimeout, то initLayout (strUserPrefs) не потому, что strUserPrefs является недействительным. Любая помощь будет оценена!

Вот код UserPreferencesManager.js:

var UserPreferencesManager = function() { 
    var strPrefsID = null; 
    var strPrefsString = null; 

    return { 

    Initialize: function (strPrefsIDIn) { 
     strPrefsID = strPrefsIDIn; 
     strPrefsString = this.GetPreferences(); 
    }, 

    GetPreferences: function() { 
     if (!strPrefsID) { 
     alert("Validation Failed: the UserPreferencesManager must be initialized prior to usage."); 
     return null; 
     } 
     if (!strPrefsString) { 
     this.LoadPreferences(); 
     return strPrefsString; 
     } 
     return strPrefsString; 
    }, 
    LoadPreferences: function() { 
     if (!strPrefsID) { 
     alert("Validation Failed: the UserPreferencesManager must be initialized prior to usage."); 
     return null; 
     }  
     myasyncfunctioncall({ 
     parameters: ["USR_PersonId", "abc", 'GET'] 
     script_name: 'MAINTAIN_USER_PREFS', 
     onexception: function (exception, xhr, options) { 
      alert('Error: ' + xhr.statusText + +exception); 
      console.log(exception); 
     }, 
     onsuccess: function (data, xhr, options) { 
      if (data == "User ID is zero") { 
      alert('MP_MAINTAIN_USER_PREFS: must be > 0.0'); 
      strPrefsString = data; 
      } 
      else { 
      strPrefsString = data; 
      } 
     } 
     }); 
    },// end of LoadPreferences 

    WritePreferences: function (strPrefsIn, strPrefsID) { 
     if (strPrefsID && typeof strPrefsID === "string") { 
     if (strPrefsIn != null) { 

      myasyncfunctioncall({ 
      parameters: ["USR_PersonId", strPrefsID, strPrefsIn , 'SET'] 
      script_name: 'MAINTAIN_USER_PREFS', 
      onexception: function (exception, xhr, options) { 
       alert('Error: ' + xhr.statusText + +exception); 
       console.log(exception); 
      }, 
      onsuccess: function (data, xhr, options) { 
       if (data == "transaction-ok") { 
       UserPreferencesManager.LoadPreferences(); 
       } else if (data == "User ID is zero") { 
       alert('MP_MAINTAIN_USER_PREFS: must be > 0.0'); 
       } 
      } 
      }); 
     } else { 
      alert("Error: Preferences object must be initialized prior to writing preferences"); 
     } 
     } else { 
     alert('Error: The preference ID can\'t be null and must to be of type string'); 
     return; 
     } 
    }// end of WritePreferences 
    };// end of return API 

}(); // end of UserPreferencesManager 
+0

Подробнее об отложенных объектах/обещаниях: http://learn.jquery.com/code-organization/deferreds/. –

+0

Спасибо, сделаю. –

ответ

1

Спасибо за подсказку, Балачандра! Вот что я сделал, добавил два параметра метода LoadPreferences - обратный вызов и strPrefsID, так что я могу вызвать функцию fnCallback в случае успеха и передать его АЯКС данные:

LoadPreferences: function (fnCallback, strPrefsID) { 
    if (!strPrefsID) { 
     alert("Validation Failed: the BhsUserPreferencesManager must be initialized prior to usage."); 
     return null; 
    } 
    if (strPrefsString) { 
     // strPrefsString is not null, so return it 
     callback(strPrefsString); 
    } else { 
     myasyncfunctioncall({ 
      parameters: ["USR_PersonId", "abc", 'GET'] 
      script_name: 'MAINTAIN_USER_PREFS', 
      onexception: function (exception, xhr, options) { 
       alert('Error: ' + xhr.statusText + +exception); 
       console.log(exception); 
      }, 
      onsuccess: function (data, xhr, options) { 
       if (data == "User ID is zero") { 
        alert('MAINTAIN_USER_PREFS: must be > 0.0'); 
        strPrefsString = data; 
       } else if (data.substring(0, 5) === "ERROR") { 
        alert(data); 
       } else { 
        fnCallback(data); 
       } 
      } 
     }); 
    } 
}// end of LoadPreferences 

А вот как теперь я могу назвать initLayout:

BhsUserPreferencesManager.LoadPreferences(initLayout, sPageIdentifier); 
0

Seens как этот myasyncfunctioncall посылает запрос асинхронной. Вам нужно будет добавить некоторую переменную, чтобы установить, пришел ли ответ этого асинхронного запроса, а затем, когда он установлен, вы можете продолжить свою процедуру.

В случае когда асинхронный вызов выполняется на javascript, программа продолжается так, как будто она уже завершена. Вы должны вручную добавлять проверки, чтобы проверить, завершено ли оно или нет.

0

UserPreferencesManager.GetPreferences() делает асинхронный вызов AJAX для получения пользовательских настроек. Итак, в этом случае поток Javascript продолжит выполнение в текущем контексте потока и выполнит initLayout (strUserPrefs). Но в этом состоянии вызов GetPreferences() все еще не завершен, а strUserPrefs имеет значение null.

SetTimeout является одним из трюков, чтобы преодолеть эту проблему, которую вы сделали. Но вы также можете создавать API-интерфейсы таким образом, чтобы он позволял выполнять функцию обратного вызова для каждого асинхронного вызова AJAX.

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