2015-09-22 3 views
0

Мне нужны некоторые данные асинхронизации в directive, эта директива повторяется, поэтому, когда приложение запускается, каждый directive вызывает данные службы, но из-за отсутствия кэшированных данных $http выполняется много раз.

Я добавил обещание внутри службы и попытался вернуть его вместо нового. он работал, но я не знаю, хорошая ли это идея?

angular.module('test') 
     .service('Users', function($q, $http) { 

     var api = 'api'; 
     var cached = []; 

     var localPromise; 

     var _getAll = function() { 

      if (localPromise) { 

       return localPromise; 
      } 

      var deferred = $q.defer(); 
      if (cached.length > 0) { 

       deferred.resolve(cached); 
       localPromise = null; 
       return deferred.promise; 
      } 

      var url = api + '/users'; 

      $http.get(url).then(function(data) { 

       cached = data.data; 
       deferred.resolve(cached); 
       localPromise = null; 
      }, function(err) { 
       deferred.reject(err); 
       localPromise = null; 
      }); 
      localPromise = deferred.promise; 
      return deferred.promise; 
     } 
     return { 
      getAll: _getAll 
     } 
    }); 

ответ

0

Вы можете, конечно, кэшировать обещание и вернуть, что к следующему абоненту, за исключением того, что может (вероятно, должно) быть сделано без $q.defer - Я вернусь к этому позже.

Поскольку ваш вопрос специфичен для $http, тем проще подход будет использовать $ HTTP встроенный кэш с { cache: true } в конфиге:

app.factory("User", function($http){ 
    var svc = { 
    getAll: function(){ 
     return $http.get("api/users", { cache: true }) 
        .then(function(response){ 
         return response.data; 
        }); 
    } 
    }; 

    return svc; 
}) 

Если вы хотите кэшировать само обещание - полезно, когда вы делаете больше, чем чистый $http - вы можете сделать это и вернуть его следующему абоненту. Вам не нужно использовать $q.defer, так как $http (или другой API на основе обещаний) уже дает обещание, поэтому просто используйте кеш. Вы также можете использовать $cacheFactory:

var usersCache = $cacheFactory("users"); 
svc.getUserDetails: function(userId){ 

    var promise = usersCache.get(userId) || 
       $http.get("api/users/" + userId) 
         .then(doSomethingCrazy) 
         .then(doSomethingCrazier); 

    usersCache.put(userId, promise); 

    return promise; 

} 
Смежные вопросы