【问题标题】:AngularJS Delay (timeout) each http call in a loopAngularJS延迟(超时)循环中的每个http调用
【发布时间】:2016-07-28 20:13:02
【问题描述】:

我有一个数组。当我通过数组循环时,我编写请求并进行 http 调用。但我希望每个 http PUT 请求都在 16 秒的间隙内发出。我尝试了 n 种方法。我尝试用 $timeout、$interval 包装 http.then 以循环 1 次,将 timeout:16000 添加到 http 配置。他们都没有延迟 http put 调用。只有第一次在循环中调用延迟。如何将每个实际的 http 调用延迟 16 秒?这是我的代码。我在 http 配置和 $timeout 中添加了超时。我一次尝试一个,两个。没有工作

angular.forEach($scope.provisionDataArray, function(provReq, index) {
      var userProvisionSCIMUrl = someurl;

      scimProvReq = prepareProvisionRequestJSON(provReq, $scope.refData, $scope.App);
      var scimReq = {
        method: 'PUT',
        url: someurl,
        headers: {
          'Content-Type': 'application/json'
        },
        timeout: 16000,
        data: scimProvReq
      }
      $timeout(function() {
            $http(scimReq).then(function successCallback(response) {

                  var provStatus = {};
                  provStatus.reqNum = index;
                  provStatus.nbid = response.data.id;
                  provStatus.id = response.data.request.id;
                  provStatus.status = response.data.request.status;
                  provStatus.statusMessage = response.data.request.statusMessage;
                  $scope.provisionStatus.push(provStatus);

                },
                function errorCallback(response) {
                  $scope.errors.push({
                        error: "Error processing,
  line: index
    });                
    }); 
 },16000,$scope.provisionDataArray.length)
 }
});

【问题讨论】:

    标签: angularjs http timeout delay


    【解决方案1】:

    你可以试试这样的。

    var scimReq = {
         method: 'PUT',
         url: someurl,
         headers: {
              'Content-Type' : 'application/json'
         },
         timeout: 16000,
         data: scimProvReq,
         index: 0
    }
    
    $scope.doIt = function() {
        if($scope.provisionDataArray.length > 0){
            $timeout(function(){
                $http(scimReq).then(function(){
                    if(scimReq.index !== $scope.provisionDataArray.length){
                        scimReq.index = scimReq.index + 1;
                        $scope.doIt();
                    }
                });
            }, scimReq.timeout);
        }
    }
    
    $scope.doIt();
    

    $interval 每 X 毫秒执行一次里面的内容。您的代码的问题在于,间隔内的唯一部分是 $http 调用,因此它将遍历并立即为每个项目调用 $interval($http)。

    【讨论】:

    • 这样只会延迟第一个请求。但随后它进行了数组 1 倍的 http 调用。不过谢谢
    • 其实不是,promise 16000ms 后再次调用该函数,下一次解决时,16000ms 后再次调用该函数。至少是这样的想法。
    • 因为我的 http 调用处于循环中,在循环时,http 调用被添加到事件队列中以供将来执行。事件队列不会被我们的代码延迟。
    • 这就是我删除循环并改用索引的原因。看看at this fiddle
    • 因为我有一个数组,所以我循环遍历数组,编写 PUT JSON,进行 http 调用。循环时,http 调用被添加到事件队列以供将来执行。事件队列不会被我们的代码延迟。那就是问题所在。如果我没有带有 in 循环的 http 调用,它可以工作
    【解决方案2】:

    使用递归策略,在前一个请求完成后调用每个请求。

    var index = 0
    
    function recursionRequests() {
      if (typeof $scope.provisionDataArray[index] == 'undefined') return; // breaking condition when reached our last request
    
      var provReq = $scope.provisionDataArray[index];
    
      var userProvisionSCIMUrl = someurl;
    
      scimProvReq = prepareProvisionRequestJSON(provReq, $scope.refData, $scope.App);
    
      var scimReq = {
        method: 'PUT',
        url: someurl,
        headers: {
          'Content-Type': 'application/json'
        },
        timeout: 16000,
        data: scimProvReq
      }
    
      $http(scimReq).then(function successCallback(response) {
          var provStatus = {};
          provStatus.reqNum = index;
          provStatus.nbid = response.data.id;
          provStatus.id = response.data.request.id;
          provStatus.status = response.data.request.status;
          provStatus.statusMessage = response.data.request.statusMessage;
          $scope.provisionStatus.push(provStatus);
        },
        function errorCallback(response) {
          $scope.errors.push({
            error: "Error processing",
            line: index
          });
    
        });
    
      $timeout(recursionRequests, 16000);
      index++;
    }
    

    更新:差点忘了超时XD

    【讨论】:

    • 没用。因为我有一个数组,所以我循环遍历数组,编写 PUT JSON,进行 http 调用。循环时,http 调用被添加到事件队列以供将来执行。事件队列不会被我们的代码延迟。那就是问题所在。如果我没有带有 in 循环的 http 调用,它可以工作
    【解决方案3】:

    我用下面的代码解决了这个问题。如果我打破循环进行http调用,我认为我可以实现延迟。所以我将我的数组切片成一个大小为 1 的块。然后添加超时。如果我将块大小设置为 2,则在 2 次调用后会添加延迟。

     var provisionChunks = sliceProvisionArray($scope.provisionDataArray, chunkSize);
     angular.forEach(provisionChunks, function(provReqs, index)  { 
        console.log("provReqs ,index ",provReqs + " " + index);
            angular.forEach(provReqs, function(provReq, index1)  { 
                setTimeout(function(x) { 
                    return function() {  
                        provisionUsers(provReq, index1, provRequestCount);                              
                     }; 
                   }(index), 12000*index);
                });
              });
    
     function sliceProvisionArray(arr, chunkSize) {
       var slicedProvArray = [], i;
          for (i = 0; i < arr.length; i += chunkSize) {
               slicedProvArray.push(arr.slice(i, i + chunkSize));
           }
           return slicedProvArray;
        }
    
    function provisionUsers(provReq, index, provReqCount) {
       var userProvisionSCIMUrl =  "https://link"
         var scimProvReq = prepareProvisionRequestJSON(provReq, $scope.referenceData, $scope.virtualApp);  
           var scimReq = makePUTSCIMReq(scimProvReq,userProvisionSCIMUrl);
           $http(scimReq).then(function successCallback(response) {  
    
            }
         },
         function errorCallback(response) {                                                       
          }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-01-13
      • 2022-01-16
      • 1970-01-01
      • 2020-12-11
      • 2016-04-13
      • 1970-01-01
      相关资源
      最近更新 更多