Подтвердить что ты не робот

Безопасно ли разрешать обещание несколько раз?

У меня есть приложение 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 и ждать, пока обещание будет разрешено. Но, учитывая, что цель этой функции состоит в том, чтобы обеспечить загрузку локали, было бы совершенно нормально, если бы пользователь вызывал ее несколько раз.

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

Из того, что я могу сказать, это работает по назначению, но мне интересно, подходит ли это подход.

4b9b3361

Ответ 1

Как я понимаю promises в настоящее время, это должно быть на 100% штрафом. Единственное, что нужно понять, это то, что когда-то разрешено (или отклонено), то есть это для объекта с отсрочкой - это делается.

Если вы должны называть then(...) на нем обещание снова, вы должны немедленно получить (первый) разрешенный/отклоненный результат.

Дополнительные вызовы resolve() не будут (не должны?) иметь какой-либо эффект. Не уверен, что произойдет, если вы попытаетесь reject отложенный объект, который ранее был resolved (я ничего не подозреваю).

Ответ 2

Если вы хотите разрешить разрешенный объект несколько раз, я рекомендую использовать "DeferredWithUpdate.js"

вы можете найти проект github здесь:

https://github.com/bennadel/DeferredWithUpdate.js

Ответ 3

Я сталкивался с такой же самое некоторое время назад, на самом деле это обещание может быть только решена раз, другой пытается ничего делать не будет (не ошибка, ни предупреждения, ни then вызова).

Я решил обойти это так:

getUsers(users => showThem(users));

getUsers(callback){
    callback(getCachedUsers())
    api.getUsers().then(users => callback(users))
}

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

Ответ 4

Что вам нужно сделать, так это положить ng-if на вашу основную ng-розетку и вместо этого показать загрузочный счетчик. Как только ваша локаль загружена, вы показываете выход и даете иерархию компонентов визуализировать. Таким образом, все ваше приложение может предполагать, что локаль загружена и проверки не требуются.

Ответ 5

Если вам нужно изменить возвращаемое значение обещания, просто верните новое значение в then и вставьте в цепочку следующие then/catch

var p1 = new Promise((resolve, reject) => { resolve(1) });
    
var p2 = p1.then(v => {
  console.log("First then, value is", v);
  return 2;
});
    
p2.then(v => {
  console.log("Second then, value is", v);
});