Angular HTTP 承诺中的竞争条件
Race condition in Angular HTTP promises
所以,我有一个小的 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 端点,但它们不需要每次都有新的结果。但这会导致丑陋的竞争条件:如果两个或多个组件在 load_posts
响应到达之前调用 get_posts
方法,那么它们都会发出 API 请求。没有副作用,因为这只是一次缓存尝试,但它破坏了整个目的。
关于如何处理这个问题有什么想法吗?
这并不是真正的竞争条件问题,只是记忆函数的问题。您可以使用 Underscore.js 中的 memoize()
之类的东西,或者自己实现它:
var load_posts = () => {
const p = $http
.get('/posts')
.then(response => response.data);
load_posts = () => p;
return p;
};
$http 服务可以缓存请求。 See here or the docs 更深入地解释缓存的工作原理。
The default $http cache can be particularly useful when our data
doesn’t change very often. We can set it like so:
$http({
method: 'GET',
url: '/api/users.json',
cache: true
});
// Or, using the .get helper
$http.get('/api/users.json', {
cache: true
});
Now, every request that is made through $http to the URL
/api/users.json will be stored in the default $http cache. The key for
this request in the $http cache is the full-path URL.
1) 将数据检索提取到单独的 "blogService" 服务中;
2) 在执行请求的服务中缓存承诺;
3) Return 对所有客户端的相同承诺,如果您不想公开整个响应对象,您可以操纵结果;
var promise = null;
function loadBlogs() {
promise = promise || $http.get("/posts").then(function(response){return reponse.data;});
return promise;
}
4) 然后只需调用服务方法并等待 promise 在您需要的任何地方解析(控制器、指令等):
function getPosts() {
blogService.loadBlogs().then(function (posts) {
vm.posts = posts;
});
所以,我有一个小的 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 端点,但它们不需要每次都有新的结果。但这会导致丑陋的竞争条件:如果两个或多个组件在 load_posts
响应到达之前调用 get_posts
方法,那么它们都会发出 API 请求。没有副作用,因为这只是一次缓存尝试,但它破坏了整个目的。
关于如何处理这个问题有什么想法吗?
这并不是真正的竞争条件问题,只是记忆函数的问题。您可以使用 Underscore.js 中的 memoize()
之类的东西,或者自己实现它:
var load_posts = () => {
const p = $http
.get('/posts')
.then(response => response.data);
load_posts = () => p;
return p;
};
$http 服务可以缓存请求。 See here or the docs 更深入地解释缓存的工作原理。
The default $http cache can be particularly useful when our data doesn’t change very often. We can set it like so:
$http({ method: 'GET', url: '/api/users.json', cache: true }); // Or, using the .get helper $http.get('/api/users.json', { cache: true });
Now, every request that is made through $http to the URL /api/users.json will be stored in the default $http cache. The key for this request in the $http cache is the full-path URL.
1) 将数据检索提取到单独的 "blogService" 服务中;
2) 在执行请求的服务中缓存承诺;
3) Return 对所有客户端的相同承诺,如果您不想公开整个响应对象,您可以操纵结果;
var promise = null;
function loadBlogs() {
promise = promise || $http.get("/posts").then(function(response){return reponse.data;});
return promise;
}
4) 然后只需调用服务方法并等待 promise 在您需要的任何地方解析(控制器、指令等):
function getPosts() {
blogService.loadBlogs().then(function (posts) {
vm.posts = posts;
});