简体   繁体   中英

Redirect to different webpage after for loop

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM