2015-12-29 3 views
1

У меня есть контроллер и обслуживание с кешированным значением.Как предотвратить одинаковые запросы на сервер?

app.service('nameService', ['$q','$http', function($q, $http){ 
 
    var that = this; 
 

 
    that.name = null; 
 

 
    this.index = function(){ 
 
     var deferred = $q.defer(); 
 

 
     if (that.name !== null) { 
 

 
      // fired cahed value 
 
      console.log('cashed'); 
 

 
      deferred.resolve(that.name); 
 

 
     } else { 
 
      $http.get('/api/name').success(
 
       function(response) { 
 

 
        // fired request to server 
 
        console.log('server'); 
 

 
        that.name = response.name; 
 
        deferred.resolve(that.name); 
 

 
       } 
 
      ); 
 
     } 
 

 
     return deferred.promise; 
 
}]);

При поступлении запросов в контроллер отправить с интервалом, как

app.controller('nameCtr', ['$scope', '$timeout', 'nameService'], 
 
       function($scope, $timeout, nameService){ 
 

 
    nameService.index(); // console.log server 
 
    
 
    $timeout(function(){ 
 
    
 
     nameService.index(); // console.log cached 
 
     
 
    },3000) 
 
    
 
    $timeout(function(){ 
 
    
 
     nameService.index(); // console.log cashed 
 
     
 
    },6000) 
 
    
 
}]);

Это все нормально, первый запрос обожженного server, другой выстрелил cached. Но если я отправлю запрос без задержки, я отправляю несколько запросов на сервер. как:

... 
 
nameService.index(); // console.log server 
 
nameService.index(); // console.log server 
 
nameService.index(); // console.log server 
 
...

Они выпустили server, но мне нужно кэшировать. У меня несколько контроллеров с одинаковой услугой. Какой лучший способ отправить только один запрос на сервер?

+1

Не дубликат, так как это касается кэширования ответа HTTP. Правильный способ состоял бы в том, чтобы передать '{cache: true}' и не кэшировать обещание в любом случае. –

ответ

1

Как предотвратить те же запросы на сервер?

Ну, вы можете изменить $http.get('/api/name') к $http.get('/api/name', {cache: true}), это на самом деле построен в угловых и работает просто отлично.

Это приводит интересный вопрос о том, как сделать это без использования помощи угловой для родового обещания - так же просто:

this._data = null; 
this.index = function() { 
    return this._data || (this._data = $http.get('/api/name')); 
} 

Таким образом, если он кэшируется она вернет левую часть, и если это не будет кешировать правую сторону.

Важной частью является то, что мы кэшировали обещание, а не данные. Это «трюк», который вам не хватало.

0

Вы можете сделать это следующим способом

app.service('nameService', ['$q','$http', function($q, $http){ 
 
    var that = this; 
 

 
    that.nameDeffered = null; 
 

 
    this.index = function(){ 
 
     if (that.nameDeffered === null) { 
 
      that.nameDeffered = $q.defer(); 
 
      $http.get('/api/name').success(
 
       function(response) { 
 
        // fired request to server 
 
        console.log('server');       
 
        that.nameDeffered.resolve(response.name); 
 
       } 
 
      ); 
 
     } 
 

 
     return that.nameDeffered.promise; 
 
    } 
 
}]);

+1

stackoverflow.com/questions/23803743/what-is-the-explicit-promise-construction-antipattern-and-how-do-i-avoid-it –

+0

Если автору необходимо кэшировать все ответы, которые возвращают $ http.get ('/api/name '), мы можем написать что-то подобное в выражении if that.nameDeffered = $ http.get ('/api/name '); Но он хочет кэшировать только response.name. Вот почему я создал новый вариант. – YuriyP

+0

Это совершенно не нужно - посмотрите на мой ответ, как это можно сделать без него. –

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