簡體   English   中英

限制同時異步$ http get請求的角度

[英]Limiting simultaneous asynchronous $http get request in angular

我有一個頁面,其中包含連接到媒體流的IP地址表。 我將它們鏈接到一個包含位置信息的數據庫,並能夠處理來自緩存的重復ips請求以減少負載。 但是,當一次發出太多請求時,頁面崩潰並顯示Error: Insufficient Resources 我嘗試使用此方法進行批處理,但是Synchronous XMLHttpRequest on main thread收到關於Synchronous XMLHttpRequest on main thread過時警告,而且它似乎也無濟於事。 如何限制一次搜索的數量? 我不想一次將它們限制為一個,否則將花費太長時間。 這是相關代碼:

angular.forEach($scope.results, function(conn, key){

    $http.get("addrinfo.cgi?action=get&addr="+conn.ip, { cache: true}) //$scope.results is list of ip addresses
                    .then(function(ipLocation) {
                        console.log(ipLocation);
                        var locationResults = ipLocation.data; 
                        conn.country = locationResults.country;
                        //... more assignments
                    });
                });

編輯:我在執行保羅的答案時遇到問題。 不斷獲取RequestManager is undefined的代碼結構,如下所示。

angular.module('ip-module', [
'app.controller',
'app.filter',
'app.factory'
]);

app.controller('ip-analysis', function($scope, $http, $q) { ... })

.filter('customNumFilter', function() { ... })

.factory('RequestManager', ['$http', '$scope', function() { ... 
}]);

您可以創建一個將處理請求的管理器。 管理器可以跟蹤正在運行的請求數,一旦達到限制,就將多余的請求重定向到隊列中。 請求完成后,並且有足夠的插槽,然后可以從隊列中拾取並運行下一個請求。

import copy

angular.module('your-module', []) 

.controller('Controller1', function(){
  .... 
}) 

.controller('Controller1', function(){
  .... 
})

.factory('RequestManager', function(){
  var manager = {
    limit: 10,
    queue: [],
    cache: {},
    requests: 0,
    sendRequest: function(conn){
      if(manager.requests < manager.limit){
        if conn.ip in manager.cache.keys():
          conn.update(manager.cache[conn.ip])
        else:
          manager.runRequest(conn);
      }else{
        manager.queue.push(conn);
      }
    },
    runRequest: function(conn){
      manager.requests++;
      $http.get("addrinfo.cgi?action=get&addr="+conn.ip, { cache: true})
        .then(function(ipLocation) {
            console.log(ipLocation);
            var locationResults = ipLocation.data; 
            conn.country = locationResults.country;
            //... more assignments
            manager.cache[conn.ip] = copy.deepcopy(conn) #use deepcopy to make sure the value is not overwritten in the $scope
            runNextRequest();
        }, function(error){
          runNextRequest();
        });
    },
    runNextRequest: function(){
      if(manager.requests > 0){
        manager.requests --;
        if(queue.length > 0){
          manager.runRequest(queue.shift());
        }
      }
    }
  }
  return manager;
}

在您的控制器中,您可以執行以下操作

angular.forEach($scope.results, function(conn, key){
  RequestManager.sendRequest(conn);
}

我不完全確定如何使用這些值,但是可以調整代碼以更適當地使用它們。

免責聲明:我沒有時間運行此代碼,因此請注意可能的錯誤。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM