Skip to content

Instantly share code, notes, and snippets.

@obrodinho
Last active May 3, 2020 21:15
Show Gist options
  • Save obrodinho/a8cbe000b1a1701434a159d0609eaa72 to your computer and use it in GitHub Desktop.
Save obrodinho/a8cbe000b1a1701434a159d0609eaa72 to your computer and use it in GitHub Desktop.
Executing simultaneous ajax requests in a chunk-based order. Slicing demand and deferring execution [jQuery][AJAX]

Slincing huge amount of requests in chunks and Deferring jQuery AJAX requests to execute a chunk at time.

Let's say, that you have a ton of ajax requests to do (what's not recomended) and parallelize all requests may turn your server unstable and your screen blocked.

In this gist I document a solution that I used to preserve the server's sake and alleviate page loading.

Scenario

So, we have elements that holds an attribute (data-async-url) that prior this kludgy solution was used by the jquery plugin async-include by Mr. Peter Coles. BTW, Thanks, Peter!

These attributes only has an url to where make an get request. The response of that request, replaces the content of the element that is holding the url.

On my case the app got ~300-400 requests to do on home page. To better perform the page load, I had a simple idea (that i don't know if is the best).

Split the execution of the parallel requests, into chunks and executes each chunk sequentially. Parallelizing the demand of the chunk.

I hope that it helps someone else. I'll test and improve the code as soon as possible.

Contributions

Any contributions are welcome. I learn a lot from other codes and solutions. I'm not a javascript developer, only a user of jQuery. Any directions in how to improve this code would be great.

(function ($) {
var MAX_REQUESTS = 10;
function performAll(chunk) {
var deferred = new $.Deferred();
var parallelRequests = [];
chunk.each(function () {
var $this = $(this);
var url = $this.data('async-url');
parallelRequests.push(getAsyncData($this, url));
});
// it is not expecting...
$.when.apply($, parallelRequests)
.done(function () {
deferred.resolve();
});
return deferred.promise();
}
function getAsyncData($element, url) {
var deferred = new $.Deferred();
$.ajax({
url: url,
dataType: 'html',
type: 'get',
success: function (html) {
console.log('DONE: ' + url);
$element.replaceWith(html);
deferred.resolve();
},
error: function (err) {
console.log('FAIL: ' + url);
$element.replaceWith("<td>ERROR</td>");
deferred.reject();
}
});
return deferred.promise();
}
$(function () {
var $asyncUrlElements = $('[data-async-url]');
var length = $asyncUrlElements.length;
if (length <= MAX_REQUESTS) {
performAll($asyncUrlElements);
} else {
var executionQueue = [];
for (var start = 0; start < length; start += MAX_REQUESTS) {
var chunk = $asyncUrlElements.slice(start, start + MAX_REQUESTS);
executionQueue.push(performAll(chunk));
}
//executing each chunk at time.
executionQueue.reduce(function (current, next) {
return current.then(next);
}, $.Deferred().resolve());
}
});
})
(jQuery);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment