I'm a little confused how to determine when async function called multiple times from another one is finished a call from the last iteration:
function MainAsyncFunction(callback) {
for (var i = 0; i < 10; i++) {
SubAsyncFunction(function(success) {
if (i >= 10 && success) { // THIS IS WRONG?!
callback(true); // happens too early
}
});
}
};
function SubAsyncFunction(callback) {
SubSubAsyncFunction(function() {
callback(true);
});
}
What I'm doing is calling the Google Distance Matrix service, which has a limitation of 25 destinations, hence I'm having to split my array of destinations to call this service multiple times but I don't understand when it's finished.
and in the main bit of code I can tell that the second iteration of the loop in the MainAsyncFunction hasn't yet completed when it does a call back.
I think my problem is I haven't got my head around the order of events when dealing with Async functions in JavaScript... please explain how the subject is normally achieved.
You could use the jQuery Deferred object, which acts as a token representing the status of an async operation.
The following is a simplified example:
//set up your sub method so that it returns a Deferred object
function doSomethingAsync() {
var token = $.Deferred();
myAsyncMethodThatTakesACallback(function() {
//resolve the token once the async operation is complete
token.resolve();
});
return token.promise();
};
//then keep a record of the tokens from the main function
function doSomethingAfterAllSubTasks() {
var tokens = [];
for (var i=0; i < 100; i++) {
//store all the returned tokens
tokens.push(doSomethingAsync());
}
$.when.apply($,tokens)
.then(function() {
//once ALL the sub operations are completed, this callback will be invoked
alert("all async calls completed");
});
};
The following is an updated version of the OP's updated code:
function MainAsyncFunction(callback) {
var subFunctionTokens = [];
for (var i = 0; i < 10; i++) {
subFunctionTokens.push(SubAsyncFunction());
}
$.when.apply($,subFunctionTokens)
.then(function() {
callback(true);
});
};
function SubAsyncFunction() {
var token = $.Deferred();
SubSubAsyncFunction(function() {
token.resolve();
});
return token.promise();
};