В моем приложении есть служба i18n, содержащая следующий код:
var i18nService = function() {
this.ensureLocaleIsLoaded = function() {
if( !this.existingPromise ) {
this.existingPromise = $q.defer();
var deferred = this.existingPromise;
var userLanguage = $( "body" ).data( "language" );
this.userLanguage = userLanguage;
console.log( "Loading locale '" + userLanguage + "' from server..." );
$http( { method:"get", url:"/i18n/" + userLanguage, cache:true } ).success( function( translations ) {
$rootScope.i18n = translations;
deferred.resolve( $rootScope.i18n );
} );
}
if( $rootScope.i18n ) {
this.existingPromise.resolve( $rootScope.i18n );
}
return this.existingPromise.promise;
};
Идея состоит в том, что пользователь позвонит ensureLocaleIsLoaded
и будет ждать выполнения обещания. Но, учитывая, что цель функции состоит только в том, чтобы гарантировать, что локаль загружена, для пользователя было бы вполне нормально вызвать ее несколько раз.
В настоящее время я просто сохраняю одно обещание и разрешаю его, если пользователь снова вызовет функцию после того, как языковой стандарт был успешно получен с сервера.
Насколько я могу судить, это работает как задумано, но мне интересно, правильный ли это подход.
javascript
angularjs
Der Hochstapler
источник
источник
Ответы:
Насколько я понимаю в настоящее время обещания, это должно быть на 100% нормально. Единственное, что нужно понять, - это то, что однажды решено (или отклонено), то есть для отложенного объекта - это сделано.
Если вы
then(...)
снова вызовете это обещание, вы должны немедленно получить (первый) разрешенный / отклоненный результат.Дополнительные вызовы
resolve()
не будут (не должны?) Иметь никакого эффекта. Не уверен, что произойдет, если вы попытаетесьreject
использовать отложенный объект, который был ранееresolved
(я ничего не подозреваю).источник
Некоторое время назад я столкнулся с тем же самым, действительно, обещание может быть выполнено только один раз, другие попытки ничего не сделают (без ошибок, без предупреждений, без
then
вызова).Я решил обойти это так:
просто передайте свою функцию как обратный вызов и вызывайте ее столько раз, сколько захотите! Надеюсь, это имеет смысл.
источник
getUsers
и затем вызывать его.then()
столько раз, сколько захотите. Нет необходимости передавать обратный вызов. На мой взгляд, одним из преимуществ обещаний является то, что вам не нужно указывать обратный вызов заранее..then
операторов. Как бы то ни было, я думаю, что единственный способ возвращать данные несколько раз в вызывающий контекст - это использовать обратные вызовы, а не обещания, поскольку обещания не были созданы для работы таким образом.Если вам нужно изменить возвращаемое значение обещания, просто верните новое значение в
then
цепочке далееthen
/catch
на нем.источник
Нет четкого способа выполнить обещания несколько раз, потому что, поскольку оно решено, оно выполнено. Лучшим подходом здесь является использование шаблона, наблюдаемого наблюдателем, например, я написал следующий код, который отслеживает событие клиента сокета. Вы можете расширить этот код, чтобы удовлетворить ваши потребности
источник
Вы можете написать тесты, чтобы подтвердить поведение.
Выполнив следующий тест, вы можете сделать вывод, что
Вы также можете проверить мою запись в блоге для подробностей.
источник
Что вам нужно сделать, так это поставить ng-if на свой основной ng-выход и вместо этого показать загрузочный счетчик. Как только ваш языковой стандарт загружен, вы показываете розетку и позволяете отображать иерархию компонентов. Таким образом, все ваше приложение может предполагать, что языковой стандарт загружен и никаких проверок не требуется.
источник