在AngularJS服务中只调用一次/缓存来自$ http的数据 [英] Calling only once / caching the data from a $http get in an AngularJS service
问题描述
这可能听起来像一个非常简单/愚蠢的问题,但我需要问它,因为我之前没有遇到过这种情况......好吧我在angularJS应用程序中有服务。此服务目前包含4个方法,所有方法都执行80%相同的功能/代码,我希望提高效率。这是我的服务看起来像(删除了大量代码):
This may sound like a really simply/stupid question but I need to ask it as I haven't came across this scenario before... okay I have a service in my angularJS app. this service currently contains 4 methods that all perform 80% the same functionality/code and I wish to make this more efficient. Here is what my service looks like (with a lot of code removed):
.factory('townDataService', function ($http) {
var townList = {};
townList.getTownList = function () {
return $http({method: 'GET', url: '/api/country/cities'})
.then(function (response) {
// HERE WE FORMAT THE response as desired... that creates a returnArray
var returnArray = [];
// loop through the countries
var JsonData = response.data;
for (key in JsonData['countries']) {
// formatting code...
}
// end of repeated CODE
return returnArray; // this is array, we don't do any formatting here
});
};
townList.getCurrentTown = function (place) {
return $http({method: 'GET', url: '/api/country/cities'})
.then(function (response) {
// HERE WE FORMAT THE response as desired... that creates a returnArray
var returnArray = [];
// loop through the countries
var JsonData = response.data;
for (key in JsonData['countries']) {
// formatting code...
}
// end of repeated code
// now the format further / work with the returnArray...
for (var i = 0; i < returnArray.length; i++) {
// do stuff
}
return currentTown; // this is a string
});
};
townList.getCurrentCountry = function (place) {
return $http({method: 'GET', url: '/api/country/cities'})
.then(function (response) {
// HERE WE FORMAT THE response as desired... that creates a returnArray
var returnArray = [];
// loop through the countries
var JsonData = response.data;
for (key in JsonData['countries']) {
// formatting code...
}
// end of repeated code
// now the format further / work with the returnArray...
for (var i = 0; i < returnArray.length; i++) {
// do stuff
}
return currentCountry; // this is a string
});
};
return townList;
}
)
;
现在我重复相同的 $ http'GET'
在返回对象数组或字符串之前,在每个方法和相同的格式代码(这是很多嵌套循环)中。这远远没有效果!将此功能放入其自身功能的最佳方法是什么,所以我们只调用一次GET url但仍返回每个方法的承诺?我应该将 $ http({method:'GET',url:'/ api / country / cities'})
的结果设置为var并注入/传递它如有必要,在格式化数据之前进入每个方法?我应该使用某种 $ cacheFactory
?
Now I repeat the same $http 'GET'
in each method and the same formatting code (which is a lot of nested loops) before returning a object array or a string. This is far from efficent! What is the best way to put this functionality into it's own function so we only call the GET url once but still return a promise with each method? Should I set the results of the $http({method: 'GET', url: '/api/country/cities'})
as a var and inject / pass it into each method before formatting the data if necessary? Should I use some sort of $cacheFactory
?
对不起,如果这是一个愚蠢的问题,如果我没有我很好地解释了这些问题。
Sorry if this is a dumb question and if I haven't explained myself well I shall rephrase the questions.
提前致谢。
推荐答案
就像你说的那样;这段代码可以(并且应该)以多种方式进行重构。一个例子:
It is just as you say; this code can (and should) be refactored in many ways. One example:
让我们将HTTP内容分解为一个单独的服务,它也将负责缓存。 (另一个想法是为HTTP /远程调用提供服务,另一个 - 也许是一般用途装饰器 - 来处理缓存。现在我们不要详细介绍。)让我们把格式化代码放入另一种方法:
Let us factor the HTTP stuff into a separate service, that will also take care of caching. (Another idea for this would be to have a service for the HTTP/remote calls and another - maybe a general use decorator - to handle caching. LEt us not go into so much detail for now.) And let us put the formatting code in another method:
远程呼叫服务:
.service('townHttpService', function($http, $q) {
var cache;
function getCities() {
var d = $q.defer();
if( cache ) {
d.resolve(cache);
}
else {
$http({method: 'GET', url: '/api/country/cities'}).then(
function success(response) {
cache = response.data;
d.resolve(cache);
},
function failure(reason) {
d.reject(reason);
}
});
}
return d.promise;
}
function clearCache() {
cache = null;
}
return {
getCities: getCities,
clearCache: clearCache
};
})
格式化程序:
.service('townFormatter', function() {
return function townFormatter(jsonData) {
// HERE WE FORMAT THE response as desired... that creates a returnArray
var returnArray = [], key;
// loop through the countries
for (key in jsonData['countries']) {
// formatting code...
}
// end of repeated CODE
return returnArray; // this is array, we don't do any formatting here
};
})
您的 townDataService
,以以上:
.factory('townDataService', function (townHttpService, townFormatter) {
var townList = {};
townList.getTownList = function () {
return townHttpService.getCities().then(townFormatter);
};
townList.getCurrentTown = function (place) {
return townHttpService.getCities().then(townFormatter).then(function(cityList) {
var currentTown;
for (var i = 0; i < cityList.length; i++) {
// do stuff
}
return currentTown; // this is a string
});
};
townList.getCurrentCountry = function (place) {
return townHttpService.getCities().then(townFormatter).then(function(cityList) {
var currentCountry;
for (var i = 0; i < cityList.length; i++) {
// do stuff
}
return currentCountry; // this is a string
});
return townList;
})
这篇关于在AngularJS服务中只调用一次/缓存来自$ http的数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!