views:

143

answers:

1

Every 3 seconds I make an AJAX POST request to get the status of a process. This works great.

When the process reaches 100% a call back function executes(indicated below) to add new elements to the page and then it cancels the setTimeout method that use to continuously get the progress every 3 seconds. However, I have been told by my users it sometimes fails to cancel and the new elements are not added to the page and I've been that it get stuck at showing "100%".

I have tested this again and again and it never gets stuck for me. The code also looks ok, but my JavaScript skills are not great so I was hoping someone could point out if there is potential of this problem happening?

I have commented the code, apologies its very long. I have tried to reduce it.

function convertNow(validURL){

    startTime = setTimeout('getStatus();', 6000); 
       //AJAX CALL TO RUN PROCESS
       $.ajax({
       type: "GET",
       url: "main.php",
       data: 'url=' + validURL + '&filename=' + fileNameTxt,
       success: function(msg){
       //ON SUCCESS CLEAR SETTIMEOUT AND SHOW ELEMENTS (text)
       clearTimeout(continueTime);
       clearTimeout(startTime);    
     $("#loading").hide("slow");
     $("#done").html("Done");   
       }//function

     });//ajax

}//function convertNow

function getStatus(){
     //AJAX CALL TO GET STATUS OF PROCESS
     $.ajax({
     type: "POST",
     url: "fileReader.php",
     data: 'textFile=' + fileNameTxt,
     success: function(respomse){
     textFileResponse = respomse.split(" ");
     $("#done").html("Processing...");
     }
     });//ajax
     clearTimeout(continueTime);

     if(textFileResponse[0]=='100.0%'){
      clearTimeout(continueTime);
     }
     else{
         clearTimeout(startTime);
      continueTime = setTimeout('getStatus();', 3000); 
     }
}
+4  A: 

There's probably a parsing error in the textFileReponse[0]=='100.0%' in some edge cases, with the value in the response not equaling exactly 100.0% (maybe there's extra whitespace, or maybe there are some minor differences on some platforms, etc...). This would cause the code to fall through to the else {} block, and your getStatus function would be queued up again.

EDIT: Given the thread in the comments, it's also an equal likelyhood that there's a race condition going on between the two blocks of Ajax code. (just putting this here for the benefit of readers). END EDIT

What you probably want, in addition to resolving the parsing, however, is to use setInterval(), with only one timer, instead of a startTime and continueTime timer. setTimeout executes only once, whereas setInterval repeats every x milliseconds, so you'd need only one. To cancel a setInterval, use clearInterval.

Jarret Hardie
If it goes to the else{} block and the process is done then the process success function should clearTimeout(continueTime) and clearTimeout(startTime), right?!
Abs
Not necessarily... getStatus() and success() are executing asynchronously, so you could end up with a race condition. Given that you have the success check, you could get rid of the string check in getStatus(). Using getInterval() alone the success area can cancel the interval without checking text
Jarret Hardie
That would also clear up the race condition, assumining that's the issue
Jarret Hardie
I can't really use setInterval since I have different amounts of seconds. Also IE doesn't play nice with setInterval. I can't see how setInterval will solve this. I think you are right about the race problem though, how can this be fixed any other ideas?
Abs
Okey dokey! Well, it's a little unusual for JS, but you could try using a lock variable that each block of code needs to "acquire" (loosely speaking) before manipulating the timeouts. Or have getStatus() check at the start to see if #done contains 'Done' before it continues?
Jarret Hardie