0

So I'm polling something pretty standard

(function poll(){
    $.ajax({ ... })
});

... and it works well. But now, I want to be able to continue polling every couple seconds and then if I don't get a response after two minutes, stop polling and raise an error.

How do I do the timeout?

Huangism
  • 16,278
  • 7
  • 48
  • 74
Cassidy
  • 3,328
  • 5
  • 39
  • 76
  • First thought is to log the current time (`new Date()`) on each poll at some level of elevated scope. Then check the difference between the previously-stored time before making your decision – ne1410s Sep 24 '14 at 19:25
  • You may be interested in http://stackoverflow.com/questions/3543683/determine-if-ajax-error-is-a-timeout which explains how to check an ajax response for timeout errors. Simply schedule a new poll on .success, and in .error check if it was a timeout error - if so, there you go. – Mike 'Pomax' Kamermans Sep 24 '14 at 19:26

1 Answers1

1

How about something like this. Init, track, and reset the polling within the ajax promises.

var pollingTimer     = null, // stores reference to the current timer id
    firstTimeoutResponse = null; // stores the start of what might be a series of timeout responses

function poll(){
  $.ajax({
    // your options here...
  }).done(function() {
    // reset the "timeout" timer
    firstTimeoutResponse = null;
  }).fail(function(jqXHR, textStatus) {
    // if the failure wasn't a timeout, short-circuit, 
    // but only after resetting the timeout timestamp
    if (textStatus !== 'timeout') {
      firstTimeoutResponse = null;

      return;
    }

    // if it was a timeout failure, and the first one (!), init the timeout count
    if (firstTimeoutResponse = null) { 
      firstTimeoutResponse = (new Date).getTime();
    }
  }).always(function() {
    // if 2 min have passed and we haven't gotten a good response, stop polling/chort-circuit
    if ((new Date).getTime() - firstTimeoutResponse > 120000) { // 120000ms = 2min
      window.clearTimeout(pollingTimer);

      return;
    }

    // queue the next ajax call
    pollingTimer = window.setTimeout(poll, 3000); // poll every 3s
  });
}

// kick things off!
poll();
deefour
  • 34,974
  • 7
  • 97
  • 90
  • Wouldn't this just have the timeout on each request? I want to have the whole polling process end after two minutes. I might be reading this wrong... the timeoutTimestamp is throwing me a bit. – Cassidy Sep 24 '14 at 20:22
  • You asked for it to continue polling every few seconds. If you get nothing but timeouts on those polling requests for 2min straight, the polling will stop. The `setTimeout` in the `always` promise queues the next polling event on every response up until 2 minutes of timeout errors. – deefour Sep 24 '14 at 20:54
  • I changed the name of that `timeoutTimestamp` for clarity. It's job is to store the timestamp of the first in what might be a series of timeout responses. If any response other than a "timeout" is received, this `firstTimeoutResponse` is cleared. – deefour Sep 24 '14 at 20:56