我有一个页面,其中包含连接到媒体流的IP地址表。我将它们链接到包含位置信息的数据库,并且能够从缓存提供重复的ips请求以减少负载。但是,当一次发出太多请求时,页面崩溃并给出Error: Insufficient Resources
。我尝试使用this进行批处理,但我收到了关于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() { ...
}]);
答案 0 :(得分:3)
您可以创建一个处理请求的经理。管理员可以跟踪正在运行的请求数,一旦达到限制,就将多余的请求重定向到队列中。请求完成后,如果有足够的插槽,则可以选择并运行队列中的下一个请求。
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);
}
我不完全确定您如何使用这些值,但您可以调整代码以更恰当地使用它们。
免责声明:我没有时间运行此代码,因此请注意可能的错误。