Your main issue is a fairly common one with callbacks which is that you're treating ajax like a synchronous call, when it's actually asynchronous. In other words, you are trying to print count
right after the call to ajax
, but count
won't be updated by that time.
var count = num_loaded;
$.ajax({
// ... this updates count some time later
});
// this happens right after we call $.ajax but before the success callback
// so count still has the same value as before we called $.ajax
console.log(count);
Here's a related question you can take a look at
Additionally, you're defining your counter inside the load()
method, which means it will be recreated on the call stack for each function call.
If you pass count
recursively through your async callbacks, it will have the correct value whenever your recursion stops (i.e. reaches the base case of maximum rows) so you must print it inside the callback:
$(document).ready(function () {
load(0, 0);
}
function load(row, count) {
$.ajax({
// ...
success: function(response) {
// ... loop that increments the count
if ( /* your base case is reached */ ) {
console.log(count);
} else {
load(row + 1, count);
}
}
});
}
}
A cleaner and more reasonable approach would be to use Promises. You can have the load()
method return a Promise that will on success either:
- resolve to the promise that loads the next row, or
- print
count
if the base case is reached.
Since Promises are chainable, we can also easily pass count
recursively:
function loadWithPromise(row, count) {
return new Promise(function(resolve) {
$.ajax({
// ...
success: function(response) {
// ... loop that increments the count
// if we reached the base case, resolve this promise (and thus the whole chain)
if ( /* your base case is reached */ ) {
resolve(count);
}
// otherwise load the next promise
else {
resolve(loadWithPromise(row + 1, count));
}
}
});
});
}
// recursively load all rows and then print count once we're done
loadWithPromise(0, 0).then(function(count) {
console.log(count);
});
If the rows don't need to be loaded sequentially, you can use Promise.all to wait for all calls to load()
to finish before printing the count
. This way you can keep all your promises in an array and let them happen independently, plus you wouldn't need recursion. The drawback though is that you would need to have count
defined globally since these promises would now be unrelated:
var count = 0;
function loadWithPromise(row) {
return new Promise(function(resolve) {
$.ajax({
// ...
success: function(response) {
// ... loop that increments the count
resolve();
}
});
});
}
var promises = [];
for (var row = 0; row < MAX_ROWS; row++) {
promises.push(loadWithPromise(row));
}
// once all loading operations have resolved, print the count
Promise.all(promises).then(function() {
console.log(count);
});