Angular HTTP中的竞争条件承诺

时间:2016-09-08 05:08:56

标签: javascript angularjs http-post angular-http

所以,我有一个小的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请求。没有任何副作用,因为这只是一次缓存尝试,但它违背了整个目的。

关于如何继续这个的任何想法?

3 个答案:

答案 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 heredocs可以更深入地了解缓存的工作原理。

  

默认的$ 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;
  });