Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angularjs/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript AngularJS:避免在收到响应之前调用同一REST服务两次_Javascript_Angularjs_Http_Asynchronous_Q - Fatal编程技术网

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

Javascript AngularJS:避免在收到响应之前调用同一REST服务两次,javascript,angularjs,http,asynchronous,q,Javascript,Angularjs,Http,Asynchronous,Q,我有两个指令,每个指令使用相同的工厂包装一个$q/$http调用 angular.module("demo").directive("itemA", ["restService", function(restService) { return { restrict: "A", link: function(scope, element, attrs) { restService.get().then(function(respons

我有两个指令,每个指令使用相同的工厂包装一个$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);
           });
       }
    };
}]);
问题:当我这样做的时候

<div item-a></div>
<div item-b></div>

我两次启动了相同的web服务,因为当get for ItemB启动时,get from ItemA仍在进行中

有没有办法让任何一个触发第二次的人知道已经有一个请求正在进行中,这样它就可以等一分钟,然后免费获取它


我考虑过制作一个$http或$q包装器,将每个URL标记为挂起或不挂起,但我不确定这是最好的方法。如果这件事悬而未决,我该怎么办?只需返回现有承诺,当另一个承诺解决时它就会解决?

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

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
           });
      }
   };
}]);

也许您可以在控制器中调用一次服务,并将对象传递到两个指令中?这非常有用。经过漫长的一天,我想我就是想不出如何回收我已经做出的承诺。我对它做了一些修改,因为我们处于严格模式,但它是您的90%。@oooyya cool.:)如果您认为它相关,请随时更新我的答案。不,您的答案没问题。有一件奇怪的事。我们使用延迟模式,以便提供程序中的.then最终通过resolve调用.then指令中的。但是,使用.finally(),顺序将是提供程序的then,提供程序的finally,指令的then-因此,当指令的then()运行时,\u dfd被清除,它爆炸了。因此,我们只是在提供程序中取消设置dfd,但在解决之后。我想有更好的方法,但这只是针对POC。在您的案例中,您根本不需要使用延迟模式。请阅读并记住,承诺链将在重新注册时按正确的顺序执行。我也非常喜欢这个答案(尤其是评论中的阅读材料),但我的linter在返回时就已经失败了| | | U cache=fn()。显然,在return语句中使用赋值是一种不好的做法(可维护的含糊不清)。只是吹毛求疵,但林特不喜欢()。使用return | | |(_cache=fn())轻松修复。