I want to make three ajax calls in a click event. Each ajax call does a distinct operation and returns back data that is needed for a final callback. The calls themselves ar
EDIT -- perhaps the best option would be to create a service endpoint that does everything the three requests do. That way you only have to do one request, and all the data is where you need it to be in the response. If you find you are doing the same 3 requests over and over again, you will probably want to go this route. It is often a good design decision to set up a facade service on the server that lumps commonly used smaller server actions together. Just an idea.
one way to do it would be to create a 'sync' object in your click handler before the ajax calls. Something like
var sync = {
count: 0
}
The sync will be bound to the scope of the success calls automatically (closure). In the success handler, you increment the count, and if it is 3 you can call the other function.
Alternatively, you could do something like
var sync = {
success1Complete: false,
...
success3Complete: false,
}
when each success is executed, it would change the value in the sync to true. You would have to check the sync to make sure that all three are true before proceeding.
Note the case where one of your xhrs does not return success -- you need to account for that.
Yet another option would be to always call the final function in your success handlers, and have it access the sync option to determine whether to actually do anything. You would need to make sure the sync is in the scope of that function though.
It's worth noting that since $.when
expects all of the ajax requests as sequential arguments (not an array) you'll commonly see $.when
used with .apply()
like so:
// Save all requests in an array of jqXHR objects
var requests = arrayOfThings.map(function(thing) {
return $.ajax({
method: 'GET',
url: 'thing/' + thing.id
});
});
$.when.apply(this, requests).then(function(resp1, resp2/*, ... */) {
// Each argument is an array with the following structure: [ data, statusText, jqXHR ]
var responseArgsArray = Array.prototype.slice.call(this, arguments);
});
Using the Spread syntax, you can now write this code like so:
$.when(...requests).then((...responses) => {
// do something with responses
})
This is because $.when
accepts args like this
$.when(ajaxRequest1, ajaxRequest2, ajaxRequest3);
And not like this:
$.when([ajaxRequest1, ajaxRequest2, ajaxRequest3]);