2

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.

0

3 Answers 3

7

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();
};​
Sign up to request clarification or add additional context in comments.

3 Comments

hey, I do like the idea but don't fully understand implementation and unfortunately it doesn't work for me. Here's a jsFiddle: jsfiddle.net/BBjbK
@Tsar, thats because I made a mistake in the code - $.when doesn't take an array so we need to use apply to get it working. I've updated the fiddle here: jsfiddle.net/stevegreatrex/BBjbK/3
now we're talking, thanks a lot, man! I'll have to read up on Deferred(); but this time it worked like a charm!
0

Perhaps the ajaxStop() event? This is a jQuery event that only fires when all active AJAX requests are completed.

Comments

0

The problem is that the value of i is constantly changing in the loop, finally being out of bounds after failing the loop conditional.

The easiest way to fix this is:

for( i=0; i<5; i++) { // or whatever your loop is
    (function(i) {
        // the value of i is now "anchored" in this block.
    })(i);
}

8 Comments

Or use $.each(data, function(index, item) { ... })
If you want to bloat the code by another several hundred commands for no good reason, sure, knock yourself out...
Assuming you're referring to jQuery, the OP's already using it (he's included the tag) so he gets each for free and I personally think its a little more readable. Point taken though
What I meant is that calling each adds another massive number of commands for JS to execute, whereas mine is as simple as it gets. I don't approve of jQuery in general for this reason. Every site I've seen that uses it lags in all browsers and all computers I test in... Meanwhile I produce similar or better effects in raw JS and have to double-check if it's supposed to go that fast.
hi the problem is different, it calls back too early - the problem is my criterion for MainFunction callback. I need to know when the very last SubFunction call is processed.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.