views:

5061

answers:

4

I've set up an AJAX page refresh with setInterval. From time to time, the server is so slow that a new request is initiated before the previous one has completed.

How can I prevent that?

+3  A: 

Use a timeout value that is shorter than your refresh interval. When the request times out, it will call the error handler so you'll need to differentiate between time out errors and other types of errors in the handler.

 $.ajax({
   type: "POST",
   url: "some.php",
   data: "name=John&location=Boston",
   timeout: 5000, /* ms or 5s */
   success: function(msg){
     alert( "Data Saved: " + msg );
   }
 });

Docs at jquery.com. Example above from same source, but with added timeout value.

tvanfosson
I missed the timeout option (was using $.getJson insted of $.ajax - less options). Thanks!
yoavf
+2  A: 

Use setTimeout instead, initiate another setTimeout only after receiving the result of the AJAX request. That way a refresh only happens after the specified period since the last refresh.

AnthonyWJones
+1  A: 

Instead of using a fixed, hard coded interval: Trigger the next refresh as the last step of handling the current one, e.g. in the "Success" (or "Complete") event callbacks.

You could add a variable that keeps track of the time the current request was sent, so that you can calculate a dynamic delay:

  1. take current time T1
  2. send asynchronous request
  3. other stuff happens...
  4. asynchronous request returns, callback executes
  5. subtract T1 from current time
  6. if result < your desired request interval, set delay value > 0
  7. if result >= your desired request interval, set delay value = 0
  8. call setTimeout with the delay value, initiating the next cycle
Tomalak
+1  A: 

What I can tell you is, use a flag in your code. Like (not what I actually recommend just a simple example)

var isWorking = false;
function doRequest(){
  if(isWorking) return;
  isWorking = true;
  $.ajax({
    ...,
    success: workWithResponse
  });
}

function workWithResponse(){
  /* doAnythingelse */
  isWorking = false;
}

setInterval(doRequest,1000);

Something like that, its primitive but you will avoid race conditions. Regards.

Ricardo Vega