如何在角度应用程序中同步HTTP请求?

时间:2016-03-25 06:18:52

标签: javascript angularjs angular-promise

我已经实现了一个cacheService,它有方法get(url),它从HTTP获取值,将它放到localStorage并返回$ q promise。在下一个.get(url)运行中,它从localStorage获取值并返回包装为$ q。

function get(url){
    var saved = JSON.parse(localStorage.getItem(url));
    if (angular.isObject(saved)){
        return $q.when(saved);
    }
    return $http.get(url).then(function(xhr){
        localStorage.setItem(url, JSON.stringify(xhr.data));
        return xhr.data;
    });
}

这是我的方法不起作用的情况 - 它产生多于1个HTTP请求。

如果我两次调用cacheService.get(url)(例如来自不同的模块):

  • 当它第一次运行时,它在localStorage中找不到缓存值并发出HTTP请求
  • 当它在第一次之后第二次运行时,第一个HTTP请求尚未完成,其结果值尚未缓存。所以我的方法第二次发出HTTP请求。

我不喜欢它。

所以问题是:

如何通过网址同步请求每个网址只有1个请求?

UPD: 我有个主意:

  • 定义var currentRequests = {};
  • 如果localStorage已缓存值,则返回
  • 如果currentRequests[url]为空,请执行请求并设置currentRequests[url] = $http.get(url) - 将承诺存储在
  • 如果currentRequsts[url]不为空,则此请求现在正在运行,然后只有return currentRequests[url];

由于JS在浏览器中的单个线程中运行,因此currentRequests是线程安全的。但它不在nodejs中。正确的吗?

你怎么看?

1 个答案:

答案 0 :(得分:1)

这可能不是那么好的解决方案。但是你可以尝试一下。

我建议你保持一系列的承诺。

var promiseArr = [];
function get(url){
    var saved = JSON.parse(localStorage.getItem(url));
    if (angular.isObject(saved)){
        return $q.when(saved);
    }
    //check if $http request for the url has a pending promise.
    if(!promiseArr.hasOwnProperty(url)){          
      promiseArr[url] = $http.get(url).then(function(xhr){
          localStorage.setItem(url, JSON.stringify(xhr.data));
          delete promiseArr[url]; //Delete the promise once resolved.. please check.
          return xhr.data;
      });
    }
    return promiseArr[url]; //return the promise from the array.   
}