2014-01-16 2 views
2

Я пытаюсь выяснить, как я должен избежать этого состояния гонки на мой код:Как избежать этого состояния гонки?

.factory('cartFactory', function ($rootScope, Restangular, $q) { 
    var cart = {items: false}; 
    var response = false; 

    return { 
     cart: cart, 
     get: function ($cart) { 
      var deferred = $q.defer(); 
      if (!cart.items) { 

       cart.items = true; 

       if (!response) { 

        //get items async 
        //simulated with $timeout 
        Restangular.oneUrl('cart_show', Routing.generate('en__RG__myapp.api.cart.show')).get().then(function ($response) { 

         response = $response; 

         deferred.resolve(response); 
        }); 
       } else { 
        //resolve promise with already loaded items 
        deferred.resolve(response); 
       } 

       deferred.promise.then(function ($response) { 
        angular.copy($response.cart, cart); 
        angular.copy($response.cart, $cart); 
       }); 
      } else { 
       angular.copy(cart, $cart); 
      } 

      return deferred.promise; 
     }, 
     set: function ($cart) { 
      angular.copy($cart, cart); 
     } 
    } 
}) 

То, что я пытаюсь сделать это, что если я называю cartFactory.get ($ Корзина) в два раза, то Аякса запрос должен быть отправлен только один раз, второй раз, когда я его вызываю, тогда, если ajax загружается, он должен обещать назначить контент, когда ответ будет полностью загружен.

ответ

0

Это то, что у меня есть для моего окончательного рабочего решения, не уверен, что оно идеально или нет. Я возвращаю свое обещание, потому что я хочу что-то сделать после загрузки тележки.

.factory('cartFactory', function ($rootScope, Restangular, $q) { 
     var cart = {items: false}; 
     var promise = false; 

     return { 
      cart: cart, 
      get: function ($cart) { 

       if (!promise) { 
        //get items async 
        //simulated with $timeout 
        promise = Restangular.oneUrl('cart_show', Routing.generate('en__RG__myadpp.api.cart.show')).get().then(function ($response) { 
         angular.copy($response.cart, cart); 
         angular.copy($response.cart, $cart); 
        }); 
       } 

       if (!cart.items) { 
        promise.then(function(){ 
         angular.copy(cart, $cart); 
        }) 
       } 

       return promise; 
      }, 
      set: function ($cart) { 
       angular.copy($cart, cart); 
      } 
     } 
    }) 
2

Служба углового наклонаможет быть настроена так, что запрос GET может быть кэширован. Это означает, что каждый запрос на один и тот же URL-адрес происходит один раз независимо от того, как часто приложение называется им и в каком порядке. Также можно настроить конфигурацию $resource (http://docs.angularjs.org/api/ngResource. $ Resource) Параметр: cache:true.

Если вы не можете использовать это, вы можете написать свой собственный кэш. Пожалуйста, посмотрите на угловые источники в функции sendReq(config, reqData, reqHeaders) (строка 7763 примерно), вы можете увидеть, как они реализуют кеш для reuqests, используя $cacheFactory.

+0

спасибо, Майкл, хороший способ. Я думаю, что restangular использует $ http и может быть настроен таким образом. Просто, что здесь я не хочу кэшировать этот путь, я хочу решить, когда кэшировать вместо этого (так как это запрос содержимого корзины, я могу отправить новый запрос снова в определенный момент). Я думаю, что мой вопрос не был ясен (это, конечно, моя вина), меня больше интересует, как правильно использовать обещание здесь. Как вы можете видеть в моем коде, я проверяю ответ, который не подходит, поскольку ответ назначается только после завершения запроса. – mr1031011

+0

Вы имели в виду эту часть angular.copy ($ response.cart, cart); в вашем promis, то функция? – michael

+0

спасибо Майкл, ты указал мне в правильном направлении, меня просто так смущает обещание (все еще запутанное прямо сейчас, очевидно). Я опубликовал обновленный код, который работает для меня. – mr1031011

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