In my AngularJS application I have an array of parameters (some IDs, for example), which should be used as a parameters for an ajax call queue. The problem is that array might contain more than 600 items and if I just recursively make the ajax call using the forEach loop, the browser page eventually stops responding before each of the requests are resolved, since each of responses updates the view. Is there a technique, which could allow to send ajax requests, for example, by 5 requests at a time asynchronously, and only when those are finished, proceed the next 5?
-
do you need to update the view after all finished or after each one finished? Promise.all ??Ilya Novojilov– Ilya Novojilov2016-09-19 14:04:53 +00:00Commented Sep 19, 2016 at 14:04
-
@IlyaNovojilov - or a third option, after each "batch" of 5 have finishedJaromanda X– Jaromanda X2016-09-19 14:14:22 +00:00Commented Sep 19, 2016 at 14:14
-
Wait, you plan on sending 600 requests?Bergi– Bergi2016-09-19 14:15:10 +00:00Commented Sep 19, 2016 at 14:15
-
yes, there's a lot of information to show on the screen, and I have a 'show all' functionality, which in summary takes 600+ requests to make.Ostap Lisovyj– Ostap Lisovyj2016-09-19 14:18:24 +00:00Commented Sep 19, 2016 at 14:18
-
You never should do that. Either change your API to answer multiple queries per request, or at least use lazy loading to request only the information the user is currently viewing. Sending 600 requests at once is a no-go.Bergi– Bergi2016-09-19 14:58:07 +00:00Commented Sep 19, 2016 at 14:58
3 Answers
I think best solution would be to change the endpoint to allow an array of Id's, but I guess that is not an option. You can use promises to limit the number of simultaneous requests:
function chunkedAjax(idArray, index, limit) {
if(index >= idArray.length) {
return;
}
var index = index || 0;
var limit = limit || 5;
var chunk = idArray.slice(index, limit);
var promises = [];
angular.forEach(chunk, function(id) {
var deferred = $q.defer();
promises.push(deferred.promise);
makeAjaxCall(id).then(function(response){
deferred.resolve();
});
});
$q.all(promises).then(function() {
chukedAjax(idArray, index + limit, limit);
});
}
This is a recursive function, so be warned. I would debug this heavily before putting into production.
You will also likely need to modify your makeAjaxCall function to return a promise if it does not already, or pass the promise object to it so that it can be resolved when the ajax call completes
Comments
Take a look at $q.all(). This lets you execute a callback if multiple requests have finished. And therefore you are able to recursively execute a limited number of requests until all items are processed.
4 Comments
n requests are fired if the success callback is called.