// web service proxy for menu webservices.factory('httpCacheService', ['$http', '$q', 'apiConfig', 'CacheFactory', '$log', 'cacheService', function ($http, $q, apiConfig, CacheFactory, $log, cacheService) { 'use strict'; var deferred, promise; //Tell $http to use a cache created by CacheFactory for a specific request var getData = function (webApiUrl, isDbRequest) { deferred = $q.defer(); promise = deferred.promise; var cacheName = constant.cache.cacheName; var start = new Date().getTime(); var isFromCache = true; var cacheKey = constant.webapi.prefix + webApiUrl; var slashIndex = PWC.nIndexOf(webApiUrl, '/', 2); var questionMarkIndex = PWC.nIndexOf(webApiUrl, '?', 1); var routePrefix, dataCache; // Check to make sure the cache doesn't already exist //get method might be return error,so use the following way if (!CacheFactory.get(cacheName)) { CacheFactory(cacheName, { storageMode: constant.cache.storageMode, // This cache will use `localStorage`. }); } dataCache = CacheFactory.get(cacheName); if (slashIndex >= 0) { routePrefix = constant.webapi.prefix + webApiUrl.substring(0, slashIndex); } else if (questionMarkIndex >= 0) { routePrefix = constant.webapi.prefix + webApiUrl.substring(0, questionMarkIndex); } else { routePrefix = constant.webapi.prefix + webApiUrl; console.warn('need to verify the routePrefix in httpCache.svc.js'); } // Now that control of inserting/removing from the cache is in our hands, // we can interact with the data in "dataCache" outside of this context, // e.g. Modify the data after it has been returned from the server and // save those modifications to the cache. this.finishedCache = false; if (dataCache.get(cacheKey) && !isDbRequest) { var data = dataCache.get(cacheKey); deferred.resolve(data.cacheResult); isFromCache = true; logTimeTakenInfo(cacheKey, start, isFromCache); promise = deferred.promise; this.finishedCache = true; return this; } else { var that = this; $http.get(webApiUrl, apiConfig.create()).success(function (data) { cacheService.getCacheByKey(routePrefix).success(function (cache) { var cacheResult = {}; isFromCache = false; deferred.resolve(data); logTimeTakenInfo(cacheKey, start, isFromCache); //if could get the last modify time from cache, then align the same cache time if (!cache && typeof (cache) != constant.common.undefined && cache != 0) { cacheResult = { 'cacheResult': data, 'cacheTime': constant.cache.defaultCacheTime }; } else { cacheResult = { 'cacheResult': data, 'cacheTime': cache.lastModifyTime }; } promise = deferred.promise; dataCache.put(cacheKey, cacheResult); that.finishedCache = true; }); }); } return this; }; var promiseSuccess = function (fn) { promise.then(function (data) { fn(data); }); return this; }; var promiseError = function (fn) { promise.then(null, function (response) { fn(data); }); return this; }; var logTimeTakenInfo = function (cacheKey, start, isFromCache) { if (isFromCache) { $log.info('time taken from cache - ' + cacheKey + ': ' + (new Date().getTime() - start) + 'ms'); } else { $log.info('time taken from server - ' + cacheKey + ': ' + (new Date().getTime() - start) + 'ms'); } }; // 加这个方法的原因是,getData 方法,在处理多个请求并发从后端取数据就会出现问题,可能是因为promise已经被替换成最新的了。 var getCache = function (webApiUrl, isDbRequest, fn) { var cacheName = constant.cache.cacheName; var start = new Date().getTime(); var isFromCache = true; var cacheKey = constant.webapi.prefix + webApiUrl; var slashIndex = PWC.nIndexOf(webApiUrl, '/', 2); var questionMarkIndex = PWC.nIndexOf(webApiUrl, '?', 1); var routePrefix, dataCache; // Check to make sure the cache doesn't already exist //get method might be return error,so use the following way if (!CacheFactory.get(cacheName)) { CacheFactory(cacheName, { storageMode: constant.cache.storageMode, // This cache will use `localStorage`. }); } dataCache = CacheFactory.get(cacheName); if (slashIndex >= 0) { routePrefix = constant.webapi.prefix + webApiUrl.substring(0, slashIndex); } else if (questionMarkIndex >= 0) { routePrefix = constant.webapi.prefix + webApiUrl.substring(0, questionMarkIndex); } else { routePrefix = constant.webapi.prefix + webApiUrl; console.warn('need to verify the routePrefix in httpCache.svc.js'); } // Now that control of inserting/removing from the cache is in our hands, // we can interact with the data in "dataCache" outside of this context, // e.g. Modify the data after it has been returned from the server and // save those modifications to the cache. if (dataCache.get(cacheKey) && !isDbRequest) { var data = dataCache.get(cacheKey); isFromCache = true; logTimeTakenInfo(cacheKey, start, isFromCache); if (fn) { fn(data.cacheResult); } } else { $http.get(webApiUrl, apiConfig.create()).success(function (data) { cacheService.getCacheByKey(routePrefix).success(function (cache) { var cacheResult = {}; isFromCache = false; logTimeTakenInfo(cacheKey, start, isFromCache); //if could get the last modify time from cache, then align the same cache time if (!cache && typeof (cache) != constant.common.undefined && cache != 0) { cacheResult = { 'cacheResult': data, 'cacheTime': constant.cache.defaultCacheTime }; } else { cacheResult = { 'cacheResult': data, 'cacheTime': cache.lastModifyTime }; } dataCache.put(cacheKey, cacheResult); //promiseSuccess(thisObj.success); if (fn) { fn(data); } }); }); } }; return { get: getData, success: promiseSuccess, error: promiseError, getCache: getCache }; }]);