2014-09-18 37 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