角度服务缓存

时间:2015-03-25 17:31:23

标签: javascript angularjs caching service promise

我试图将$ http的响应缓存到角度会话的对象中,所以一旦初始调用完成,每次调用service.getCategories()(例如),都会得到数据从对象而不是api。

该服务正在路由中解析,但有身份验证,将重定向到另一个路由 - 再次调用service.getCategories()。

我通过在调用时设置init变量来尝试这个,然后所有其他调用将指向填充的对象 - 但它似乎以某种方式重置服务,并且返回的对象被填充两次,所以&#39一切都是双重的。见下文:

var $ = require('jquery');

module.exports = angular.module('app.common.services.category', [])
  .factory('categoryService', ['$http', '$q', '$rootScope', function($http, $q, $rootScope) {

// API Parameters
var deferred = $q.defer();

// Services
var Categories = {

  init: false,
  categories: [],
  index: 0,

  // Retrieve all data on load.
  // Loaded into an array for all other services
  // to use after init.
  getCategories: function(page) {

    if(!Categories.init) {

      $http.get('api/core/get_category_index')
           .then(function(result) {

        var data = result.data.categories;

        $.each(data, function(i, category) {
          category.index = Categories.index;
          Categories.categories.push(category);
          Categories.index++;
        });

        Categories.init = true;

        return deferred.resolve(Categories.categories);

      });

      // Return promise once catgories is resolved
      return deferred.promise;

    } else {


      return Categories.categories;

    }

  },

  allCategories: function() {

    return Categories.categories;

  }

}

return Categories;

}]);

1 个答案:

答案 0 :(得分:1)

您的方法存在的问题是第二次调用服务函数getCategories时,第一次服务器请求可能无法解析,导致第二次调用服务器。因此,您应该在函数调用init之后直接移动getCategories标志。

另一个问题是,在您的情况下,您不知道该函数是返回promise还是Array。我建议总是返回一个数组

module.exports = angular.module('app.common.services.category', [])
.factory('categoryService', ['$http', '$q', '$rootScope', function($http, $q, $rootScope) {

// API参数         var deferred;

//服务         var Categories = {

        categories: [],
        index: 0,

        // Retrieve all data on load.
        // Loaded into an array for all other services
        // to use after init.
        getCategories: function(page) {

            if(!deferred) {

               // replacement for intit flag
                deferred = $q.defer();

                $http.get('api/core/get_category_index')
                    .then(function(result) {

                        var data = result.data.categories;

                        $.each(data, function(i, category) {
                            category.index = Categories.index;
                            Categories.categories.push(category);
                            Categories.index++;
                        });


                        deferred.resolve(Categories.categories);

                    });


            }

             // always return a promise
             return deferred.promise;



        },

        allCategories: function() {

            return Categories.categories;

        }

    }

    return Categories;

}]);

也许您可以使用承诺返回服务本身。然后你可以在任何地方写点:

myService.load().then(
 function success(theService) {
    theService.allCategories()
 }
);

现在无论是否加载服务都无关紧要