Angular 服务缓存

Angular service cache

我正在尝试将来自 $http 的响应缓存到 angular 中会话的对象中,因此一旦完成初始调用,每隔一次调用 service.getCategories()(例如), 将从对象中获取数据而不是 api.

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

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

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;

}]);

你的方法有一个问题,当服务函数getCategories第二次被调用时,第一次服务器请求可能没有得到解决,导致第二次调用服务器。所以你应该在函数调用 getCategories.

之后直接移动 init 标志

另一个问题是,在您的情况下,您不知道函数将 return 是一个承诺还是一个数组。我建议总是 returning 一个数组

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

// API 参数 延迟变量;

// 服务 变量类别 = {

        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;

}]);

也许您可以 return 承诺服务本身。然后你可以到处写这样的东西:

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

现在之前是否加载服务已经不重要了