我正在实现自己的缓存,因为我需要它来了解我的应用程序的语义。我正在访问REST服务的客户端API中实现缓存。逻辑很简单:我首先查看自己的对象字典,如果请求的对象不存在,那么我使用网络从REST服务请求对象。即使请求的对象在我的缓存中,使用客户端API的代码也会期望一个承诺。我的问题是:为缓存中的对象实现promise / deferred模式的最佳方法是什么?现在我正在使用超时功能来做到这一点。超时功能是否足够好:?我有什么保证在API的用户收到promise对象后执行timeout函数?要查看我的问题的详细信息,请参阅以下代码:
简化代码以仅显示与问题相关的内容:
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 :(得分: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);
}
甚至更好,而不是将数据放在缓存中,您可以将promise本身放在缓存中。
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;