I'm trying to get some javascript to run a for
loop which will create an xml file and then, after the loop is complete, to visit a link that would allow the user to download the file. Currently what happens is that it gets half-way through creating the file and then sends the user the link to download the file.
I followed this question's advice and created a callback variable and moved the download link to another function, however that hasn't solved the problem either. Does anyone else have any idea how to do it? My code is:
var callbackcount=0;
function populateTemplate(numResults) {
for (i=1; i < numResults; i++) {
$.post('linkToTheFileThatCreatesTheXMLFile', {WithSomeParameters};
download(numResults);
}
}
function download(numResults) {
callbackcount++;
if (callbackcount == numResults) {
window.location.href="linkToPHPThatDownloadsFile";
}
}
Thanks heaps
Edit: Console.log results:
LOG: 230 LOG: 330 LOG: 230 LOG: 330
LOG: 430 LOG: 530 LOG: 630 LOG: 730
LOG: 830 LOG: 930 LOG: 1030 LOG: 1130
LOG: 1230 LOG: 1330
If numResults = 7
LOG: 27 LOG: 37 LOG: 47
or
LOG: 27 LOG: 37 LOG: 47 LOG: 57
etc.
Edit: The new code:
function populateTemplate(numResults) {
var callbackcount = 1;
for (i=1; i < numResults; i++) {
$.post('linkToTheFileThatCreatesTheXMLFile', {WithSomeParameters}, function() {
callbackcount++;
console.log(callbackcount, numResults);
if(callbackcount === numResults - 1) {
window.location.href="linkToPHPThatDownloadsFile";
}
});
}
}
$.post
is asynchronous call. So by the time you get to the last loop, where in the closure callbackcount
will equal numResults
all the posts won't have gone through yet. definitly not the last one.
$.post
allows for a callback which is called once the post is complete. This callback should call your download
methods.
var callbackcount=0;
function populateTemplate(numResults) {
for (i=1; i < numResults; i++) {
$.post('linkToTheFileThatCreatesTheXMLFile', {WithSomeParameters}, function() {
callbackcount++;
if (callbackcount === numResults) {
window.location.href="linkToPHPThatDownloadsFile";
}
});
}
}
This way you evaluate the function when ever the post is complete. Also I inlined it to make the access of the variables a little esier.
BTW: always use ===
over ==
in JavaScript See why
EDIT
The loop index i
should start at 0. Also it should be declared as a local variable, not global.
for ( var i = 0; i < numResults; i++ )
Otherwise the loop will only run 5 times with a numResults
of 6.
EDIT 2 - Second approach
If it has to do with too many requests per frame (which I doubt) You could also try this and see if it makes a difference.
var callbackcount=0;
function populateTemplate(numResults) {
for (i=1; i < numResults; i++) {
setTimeout( function() {
$.post('linkToTheFileThatCreatesTheXMLFile', {WithSomeParameters}, function() {
callbackcount++;
if (callbackcount === numResults) {
window.location.href="linkToPHPThatDownloadsFile";
}
});
}, 100);
}
}
this delays every request and therefore has not every request going in one frame.
It looks like you are using jQuery. The code you posted is incorrect, it should be this:
$.post( 'linkToTheFileThatCreatesTheXMLFile', {Parameters}, function() {
download(numResults);
});
(Unless your code formatting just got messed up)
also, make sure numResults
is defined and initialized up by callbackcount. (might be a scoping issue)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.