所以,我有一个小的API交互代码,如下所示:
function load_posts() {
return $http
.get('/posts')
.then(on_success);
function on_success(response) {
return response.data;
}
}
function get_posts() {
if (blog.posts) {
return $q.when(blog.posts);
}
return load_posts().then(function (posts) {
blog.posts = posts;
return blog.posts;
});
}
我这样做是为了避免始终使用相同的结果来访问API。我有几个单独的指令和组件可能需要调用此API端点,但它们不需要每次都有新的结果。但是这导致了一个丑陋的竞争条件:如果两个或更多组件在get_posts
响应到来之前调用load_posts
方法,那么它们都会发出API请求。没有任何副作用,因为这只是一次缓存尝试,但它违背了整个目的。
关于如何继续这个的任何想法?
答案 0 :(得分:0)
这不是真正的竞争条件问题,只是记忆功能的问题。您可以使用Underscore.js中的memoize()
之类的内容,或者自己实施:
var load_posts = () => {
const p = $http
.get('/posts')
.then(response => response.data);
load_posts = () => p;
return p;
};
答案 1 :(得分:0)
$ http服务可以缓存请求。 See here或docs可以更深入地了解缓存的工作原理。
默认的$ http缓存在我们的数据时特别有用 不经常改变。我们可以这样设置:
$http({ method: 'GET', url: '/api/users.json', cache: true }); // Or, using the .get helper $http.get('/api/users.json', { cache: true });
现在,每个通过$ http发送到URL的请求 /api/users.json将存储在默认的$ http缓存中。关键 $ http缓存中的此请求是完整路径URL。
答案 2 :(得分:-2)
1)将数据检索提取到单独的“blogService”服务中;
2)执行请求的服务中的缓存承诺;
3)为所有客户返回相同的承诺,如果你不想暴露整个响应对象,你可以操纵结果;
var promise = null;
function loadBlogs() {
promise = promise || $http.get("/posts").then(function(response){return reponse.data;});
return promise;
}
4)然后只需调用服务方法并等待承诺在任何需要的地方解决(控制器,指令等):
function getPosts() {
blogService.loadBlogs().then(function (posts) {
vm.posts = posts;
});