Reputation: 3541
I have some javascript code which executes when a link is clicked.
after that code has executed I want to display an alert, however the alert is being shown before the earlier code completes
document.querySelector('.btn-primary').addEventListener('click', function(evt) {
var loops = 10;
var chunkLength = Math.ceil(file.size / loops);
var start = 0;
var stop = chunkLength;
for (var i = 0; i < loops; i++) {
var blob = file.slice(start, stop);
readText(blob);
start = stop;
stop += chunkLength;
}
alert('entire file loaded');
print();
}, false);
I know because the readText method updates a progress bar and this happens after the alert pops up, its not an ajax call just a local method (which is asynchronous...)
eventually, I'm looking to replace the alert with a call to save a file but its no use if the file content hasn't been generated yet as I just save an empty file.
Upvotes: 2
Views: 959
Reputation: 598728
In that case, you'll need to extend readText
to accept a callback function:
function readText(blob, callback) {
var reader = new FileReader();
reader.onload = callback;
// whatever else your function does to load the file
}
Then you invoke it like this:
readText(blob, function() {
alert('entire file loaded');
});
Of course if readText
itself delegates its asynchronous work somewhere else, you'll have to pass the callback there too.
If the actual asynchronous function doesn't accept a callback parameter, you'll want to check for another way that it signals its caller of completeness. It may fire events. But that all really depends on how readText
is implemented.
Upvotes: 1
Reputation: 95508
You mentioned that readText
is an asynchronous method. This is why the alert
shows before readText
has finished executing. The for
loop will run through all its iterations by which time calls to readText
have not finished. The next statement to execute after the for
, is the alert
which is what you're seeing.
If readText
provides a callback function, you will have to use that:
var counter = 0;
for (var i = 0; i < loops; i++) {
var blob = file.slice(start, stop);
readText(blob, function() {
counter++;
if(counter === loops) {
alert("entire file loaded");
}
});
start = stop;
stop += chunkLength;
}
This doesn't guarantee order of operations however. It is entirely possible that a call on a later iteration finishes before a call from an earlier iteration.
If readText
doesn't have a callback argument and you can modify the source of that function, you will have to do something like this:
function readText(blob, callback) {
...
if(typeof callback === "function") {
callback();
}
}
Upvotes: 1