I'm working on a client-side JS app which is supposed to read a CSV file, make a few API calls per row, then write the results back out to CSV. The part I'm stuck on is how to orchestrate the requests and fire off a function when all are complete. This is what I have so far:
var requests = [];
// loop through rows
addresses.forEach(function (address, i) {
// make request
var addressRequest = $.ajax({
dataType: 'json',
url: 'http://api.com/addresses/' + address,
success: function (data, textStatus, jqXhr) { APP.didGetAddressJson(data, i, jqXhr) },
error: function (jqXhr, textStatus, errorThrown) { APP.didFailToGetAddressJson(errorThrown, i) },
});
requests.push(addressRequest);
// make some more requests (handled by other success functions)
});
// leggo
$.when.apply($, requests).done(APP.didFinishGeocoding);
The problem is that if one of the rows throws a 404 the done
function isn't called. I switched it to always
and now it's getting called, but not at the end -- it's usually somewhere in the middle if I log the execution of each callback to the console. However, if I edit the CSV so there are no errors it gets called at the end as expected. Am I doing something here that's allowing the always
to fire early?
Update: could it just be that the console's logging it out of order?
You need to prevent error(s) sending the promise returned by
$.when.apply($, requests)
down the error path.This can be achieved by :
.then()
to your$.ajax()
calls, rather than specifying "success" and "error" handlers as$.ajax()
options.This approach also allows you to control the data that's eventually delivered to
APP.didFinishGeocoding()
With a few assumptions, the general shape of your code should be as follows :
Tweak as necessary.
Try passing both resolved , rejected jQuery promise object through a
whenAll
function , filtering resolved, rejected promise object within.then()
at completion ofwhenAll
. See also Jquery Ajax prevent fail in a deferred sequential loope.g
jsfiddle http://jsfiddle.net/guest271314/ev4urod1/