Yes, the console.log
happens first because getJSON
is asynchronous. Your code starts it, but it finishes later, after the subsequent code runs.
To handle that, you'll need to use the "completion" callback on getJSON
. Your code above would remember how many calls it's started, and wait for that many completions before continuing.
You can also have your populateDataRow
function return the return value of getJSON
, save up those objects, and then use jQuery.when
to get a notification when they've all finished.
Here's an example: Live Copy | Live Source
var deferreds = [],
index;
for (index = 0; index < 4; ++index) {
deferreds.push($.getJSON("http://jsbin.com/agidot/1", function() {
display("One finished");
}));
}
$.when.apply($, deferreds).then(function() {
display("All finished")
});
function display(msg) {
$("<p>").html(String(msg)).appendTo(document.body);
}
Note that we only see "All finished" when all four calls have finished.
The call to $.when
is a bit of a hassle. For some reason, you can't just pass an array of Deferred
objects into it. So I used Function#apply
to call it and pass each entry of the array as a discrete argument.
I was surprised that $.when
doesn't accept an array and handle that usefully, but I see other answers here also saying to use apply
: Here and Here.
If you were going to use arrays a lot, I think I'd probably have this in my standard toolkit of jQuery extensions:
(function($) {
$.whenAll = function(deferreds) {
return $.when.apply($, deferreds);
};
})(jQuery);
...and then the end of the code example above would be:
$.whenAll(deferreds).then(function() {
display("All finished")
});