如何避免这种竞争条件?

时间:2014-01-16 06:08:21

标签: angularjs

我正在试图弄清楚如何在我的代码中避免这种竞争条件:

.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($ cart),那么ajax请求应该只发送一次,第二次我调用它然后如果正在加载ajax那么它应该承诺在完全加载响应时分配内容。

2 个答案:

答案 0 :(得分:2)

可以配置角度的$http服务,以便缓存GET请求。这意味着无论应用程序调用它们的次数多少,所有对同一URL的请求都会发生。此外,$resource服务可以采用相同的方式进行配置(http://docs.angularjs.org/api/ngResource。$ resource)参数:cache:true

如果您不能使用它,您可以编写自己的缓存。请查看函数sendReq(config, reqData, reqHeaders)(约7763行)中的角度源,您可以看到它们如何使用$cacheFactory实现缓存以获得重新生成。

答案 1 :(得分: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);
            }
        }
    })