I need to make sequential asynchronous ajax requests with limited streams. As of now I am allowed to occupy only one stream on web server so I can only do one ajax request at time.
I have following function which helps me when I am allowed to use only one stream at a time.
function initiateChain() {
var i = 0;
var tasks = arguments;
var callback = function () {
i += 1;
if (i != tasks.length) {
tasks[i](callback); //block should call callback when done otherwise loop stops
}
}
if (tasks.length != 0) {
tasks[0](callback); //initiate first one
}
}
Say if I have three ajax helper functions
function getGadgets(callback) {
//ajax call
callback(); // I call this in complete callback of $.ajax
}
function getBooks(callback) {
//ajax call
callback(); // I call this in complete callback of $.ajax
}
function getDeals(callback) {
//ajax call
callback(); // I call this in complete callback of $.ajax
}
following call ensures that no more than 1 ajax request is made from this client
initiateChain(getGadgets, getBooks, getDeals);
Now I need to enhance initiateChain to support arbitrary number of streams. Say I am allowed to use 2 or n number of streams I would like to know ideas to do so without changing ajax helper functions getGadgets, getDeals, getDeals.
In short, I have a set of functions, N, in this case getGadgets, getDeals and getDeals(|N|=3) that each need a connection to the web server. Currently, I can only execute one request at a time, so initiateChain function calls the three methods in sequence. If I had access to M connections, I would like to execute |N| functions in parallel (up to a maximum of M).
If you're using jQuery then you can use its .queue method to queue up your ajax calls and then execute them in sequence. To run multiple sequences, you can wrap the initial dequeue in a loop.
function add_api_call_to_queue(qname, api_url) {
$(document).queue(qname, function() {
$.ajax({
type : 'GET',
async : true,
url : api_url,
dataType : 'json',
success : function(data, textStatus, jqXHR) {
// activate the next ajax call when this one finishes
$(document).dequeue(qname);
}
});
});
}
$(document).ready(function() {
var queue_name = 'a_queue';
var concurrent_calls = 2;
// add first AJAX call to queue
add_api_call_to_queue(queue_name, '/example/api/books');
// add second AJAX call to queue
add_api_call_to_queue(queue_name, '/example/api/dvds');
// add third AJAX call to queue
add_api_call_to_queue(queue_name, '/example/api/shoes');
// start the AJAX queue
for (i=0;i<concurrent_calls;i++) {
$(document).dequeue(queue_name);
}
})
As long as your callbacks are all synchronous this should work for you, if not put you on the right track
var initiateChain = function () {
var args = arguments,
index = 0,
length = args.length,
process = function ( index ) {
if ( index < length ) {
$.ajax({
url: '/example.php',
complete: function () {
// Callbacks get run here
args[ index ];
process( ++index );
}
});
}
};
if ( length ) {
process( 0 );
}
};
initiateChain( getGadgets, getDeals, getDeals );
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With