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