2014-09-18 58 views
0

我正在實現自己的緩存,因爲我需要知道我的應用程序的語義。我正在實現訪問REST服務的客戶端API中的緩存。邏輯很簡單:我首先查看我自己的對象字典,如果請求的對象不存在,那麼我使用網絡從REST服務請求對象。即使請求的對象位於我的緩存中,使用客戶端API的代碼也會期待承諾。我的問題是:爲緩存中的對象實現promise/deferred模式的最佳方式是什麼?現在我正在使用超時功能來做到這一點。超時功能是否足夠好:?我有什麼保證,超時功能將在API的用戶收到承諾對象後執行?要看看我的問題的詳細信息,請參見下面的代碼:

簡化代碼,只顯示什麼是相關的問題:

angular.module("myApp").factory("restClient", function($q, $http, $timeout, cache){ 

    var get_content=function(link){ 
     var deferred=$q.defer(); 
     $http.get(link) 
     .success(function (data) { 
      deferred.resolve(data); 
      deferred=null; 
     }) 
     .error(function (error) { 
      deferred.reject(error); 
      deferred=null; 
     }); 

     return deferred.promise; 
    }; 

return{ 

     getObject : function(objectId) { 
      //If object is in the cache 
      if (cache.contains(objectId)){ 

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

        var objectContent=cache.get(objectId); 
        deferred.resolve(objectContent); 
        deferred=null; 

      }); 
      return deferred.promise; 


      } 
      else{ 

      //Create link 
      //return promise 
      return get_content(link); 
     } 
    } 
}); 
+0

你在哪裏放入緩存? – PSL 2014-09-19 00:01:53

+0

我也必須在客戶端放入緩存,但是我忽略了該算法的細節。 – 2014-09-19 00:02:36

+0

你已經留下評論,你收回了...? – PSL 2014-09-19 03:39:37

回答

1

與你正在嘗試做的,一個重要的事情如果已經有對象返回承諾,例如: - $http$timeout,則不要創建冗餘延遲承諾對象。你可以這樣做: -

var get_content=function(link){ 
     return $http.get(link) 
     .then(function (response) { 
      cache.put(link, response.data); 
      return response.data; 
     }, function(response){ 
      return $q.reject(response.data); 
     }); 

    }; 

return { 

     getObject : function(objectId) { 
      //If object is in the cache 
      if (cache.contains(objectId)){ 
      return $q.when(cache.get(objectId)) 
      } 
      return get_content(objectId); 
     } 

或者更好,而不是將數據放入緩存中,您可以將承諾本身放到緩存中。

getObject : function(objectId) { 
    if (cache.contains(objectId)){ 
     return cache.get(objectId); 
    } 

    var promise = $http.get(objectId) 
     .then(function (response) { 
      //Incase you have any condition to look at the response and decide if this is a failure then invalidate it here form the cache. 
      return response.data; 
     }, function(response){ 
      cache.remove(objectId); //Remove it 
      return $q.reject("Rejection reason"); 
     }); 
     } 
     cache.put(objectId, promise); 
    return promise; 
+0

這太棒了。非常感謝! – 2014-09-19 00:07:46

+0

@ASDF不客氣.. :) – PSL 2014-09-19 00:10:13

+0

@ASDF一個問題爲什麼不能使用http默認緩存,通過設置緩存:true爲您的獲取請求,只有url是不同的正確? – PSL 2014-09-19 04:18:39