最近有一個新項目是基于ANGULARJS開發(fā)的, 涉及到前端接口緩存以及如何更新緩存的問題. 要做到對開發(fā)者透明, 所以選擇從攔截器下手, 在發(fā)請求前通過一個唯一的key值去讀緩存中的數(shù)據(jù), 如果有緩存, 則直接返回緩存, 如果沒有緩存, 就向服務器發(fā)起請求, 并在請求成功后緩存response. 所有的開發(fā)者不需要關(guān)心如何去處理緩存. 偽代碼如下
request: function(){
if(cache[hashKey]){
return cache[hashKey];
}else{
doRequest();
cache.set(hashKey, response)
}
}
如何生成唯一的hashKey?
利用RESTFUL基于資源的URI設計, 一個資源就可以用一個URI(統(tǒng)一資源定位符)指向它, 而且每個資源對應一個特定的URI, 這完全符合我們對于hashKey唯一性的要求.
如何實現(xiàn)緩存對象?
ANGULARJS的$cacheFactory可以為我們提供一個緩存對象, 并賦值給$http.config中的cache字段.
利用$resource封裝一個最基本的具有增刪改查功能API
angular.module('app')
.factory('examineAPI', function (API_SERVER, $resource, $cacheFactory) {
var cache = $cacheFactory('examine', {capacity: 20});
return $resource(API_SERVER + 'api/examine/:action/:id',
{
id: '@id',
action: '@action'
},
{
list: {
method: 'GET',
cache: cache,
params: {
action: 'list'
}
},
view: {
method: 'GET',
cache: cache,
params: {
action: 'view'
}
}
create: {
method: 'POST',
cache: cache,
params: {
action: 'create'
}
},
update: {
method: 'PUT',
cache: cache,
params: {
action: 'update'
}
},
delete; {
method: 'DELETE',
cache: cache,
params: {
action: 'delete'
}
}
}
)
})
攔截器代碼, 若請求為查詢操作(GET), 曾默認走緩存, 若請求為非查詢操作(SAVE,UPDATE,DELETE)仿荆,成功后需要重新刷新cache(清空對應cache). 默認cache為$http
angular.module('app')
.factory('cacheInterceptor', function () {
return {
request: request,
response: response
};
function clearCache(config, key) {
(angular.isObject(config.cache) ? config.cache : $cacheFactory.get("$http"))[key ? 'remove' : 'removeAll'](key);
}
function request(config){
if (config.method === 'GET' && config.params && config.params.$forceRefresh) {
clearCache(config);
}
return config;
}
function response(res){
var config = res.config;
if (config.method !== 'GET' && config.cache) {
clearCache(config);
}
return res;
}
});
在config函數(shù)中配置
$httpProvider.interceptors.push('cacheInterceptor');
大功告成, 開發(fā)者無需關(guān)心緩存的處理, 完全透明.
examineAPI.query(); //發(fā)起GET請求, 返回examines數(shù)組, 結(jié)果被緩存
examineAPI.query(); //不發(fā)請求, 直接返回緩存
examineAPI.update({id: 1}) //發(fā)起PUT請求, 緩存會清空
examineAPI.query(); //重新發(fā)起GET請求, 返回examines數(shù)組, 結(jié)果被緩存