2014-01-16 65 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

可以將$http角度的服務配置爲可以緩存GET請求。這意味着無論應用程序多麼頻繁地調用它們,並且按照最後的順序,對同一個URL的所有請求都會發生一次。此外,$resource服務可以用相同的方式配置(http://docs.angularjs.org/api/ngResource。$ resource)參數:cache:true

如果你不能使用它,你可以編寫你自己的緩存。請查看函數sendReq(config, reqData, reqHeaders)(約7763行)中的角源,您可以看到它們如何通過使用$cacheFactory來實現reuqest的緩存。

+0

謝謝邁克爾,很好的方式。我認爲restangular使用$ http,並且可以這樣配置。只是在這裏我可能不想緩存這種方式,我想決定什麼時候緩存(因爲這是一個請求購物車的內容,我可能想在某個時候再次發送一個新的請求)。我認爲我的問題不清楚(當然這是我的錯),我更關心如何在這裏正確使用諾言。正如你在我的代碼中看到的,我正在檢查響應,這是不正確的,因爲只有在請求完成時纔會分配響應。 – mr1031011

+0

你是不是指這部分angular.copy($ response.cart,cart);在你的promis然後功能? – michael

+0

感謝邁克爾,你指出我正確的方向,我只是很混淆諾言thingy(顯然仍然困惑)。我發佈了適用於我的更新代碼。 – mr1031011