AngularJS:避免在收到响应之前调用两次相同的REST服务

ooo*_*aya 8 javascript asynchronous http angularjs q

我有两个指令,每个指令使用包含$ q/$ http调用的同一个工厂.

angular.module("demo").directive("itemA", ["restService", function(restService) {
    return {
        restrict: "A",
        link: function(scope, element, attrs) {
            restService.get().then(function(response) {
                // whatever
            }, function(response) {
               // whatever
            });
        }
    };
}]);


angular.module("demo").directive("itemB", ["restService", function(restService) {
    return {
        restrict: "A",
        link: function(scope, element, attrs) {
            restService.get().then(function(response) {
                // whatever
            }, function(response) {
               // whatever
            });
        }
    };
}]);

angular.module("demo").factory("restService", ["$http", "$q", function($http, $q) {
    return {
       get: function() {
           var dfd = $q.defer();
           $http.get("whatever.json", {
               cache: true
           }).success(function(response) {
              // do some stuff here
              dfd.resolve(response);
           }).error(function(response) {
              // do some stuff here
              dfd.reject(response);
           });
       }
    };
}]);
Run Code Online (Sandbox Code Playgroud)

问题:我这样做的时候

<div item-a></div>
<div item-b></div>
Run Code Online (Sandbox Code Playgroud)

我得到两次相同的Web服务,因为当ItemB的GET进行时,ItemA的GET仍在进行中.

有没有办法让第二个火灾知道已经有一个请求正在进行中,以便它可以等一下并免费获取它?

我已经考虑过制作一个$ http或$ q包装器,它将每个URL标记为挂起或不挂起,但我不确定这是最好的方法.如果有待处理,我该怎么办?只需返回现有的承诺,它将在另一个结算时解决?

PSL*_*PSL 18

是的,您需要做的就是在请求完成后缓存承诺并将其清除.中间的任何后续请求都可以使用相同的承诺.

angular.module("demo").factory("restService", ["$http", "$q", function($http, $q) {
    var _cache;
    return {
       get: function() {
          //If a call is already going on just return the same promise, else make the call and set the promise to _cache
          return _cache || _cache = $http.get("whatever.json", {
               cache: true
           }).then(function(response) {
              // do some stuff here
              return response.data;
           }).catch(function(response) {
              return $q.reject(response.data);
           }).finally(function(){
              _cache = null; //Just remove it here
           });
      }
   };
}]);
Run Code Online (Sandbox Code Playgroud)

  • 我也非常喜欢这个答案(尤其是评论中的阅读材料),但我的短信在回归_cache || _cache = fn().显然,在return语句中使用赋值是不好的做法(可维护模糊).只是一个挑剔,但没有喜欢(http://eslint.org/docs/rules/no-return-assign.html).使用return _cache ||轻松修复 (_cache = fn()). (4认同)