1

Given the following jQuery code

function poll(){ 
    $.ajax({ url: /myurl, 
        success: function(data){ 
            //do stuff
        }, 
        dataType: "json", 
        complete: poll, 
        error: function(jqXHR, exception) {
            if (jqXHR.status === 0) {
                $("#ajax-msg").html("Not connect.\n Verify Network.");
            } else if (jqXHR.status == 404) {
                $("#ajax-msg").html("Requested page not found. [404]");
            } else if (jqXHR.status == 500) {
                $("#ajax-msg").html("Internal Server Error [500]");
            } else if (exception === 'parsererror') {
                $("#ajax-msg").html("Requested JSON parse failed.");
            } else if (exception === 'timeout') {
                $("#ajax-msg").html("Time out error.");
            } else if (exception === 'abort') {
                $("#ajax-msg").html("Ajax request aborted.");
            } else {
                $("#ajax-msg").html("Uncaught Error.\n" + jqXHR.responseText);
            }
            //wait for some interval and then try to poll again
         },
         timeout: 10000 
    });
}

On an error condition, I would like the poll() function to be called again in 1s, 2s, 4s, 8s, 16s, 32s, 1m, 2m, 4m, 10m, 20m, 30m, 40m...

I have read that using a sleep is not correct. I would like to know the proper way to 'sleep', set an interval, or timeout to accomplish this.

  • possible duplicate of [How do I resend a failed ajax request?](http://stackoverflow.com/questions/8881614/how-do-i-resend-a-failed-ajax-request) – user2284570 Oct 10 '14 at 19:01

3 Answers3

1

simply use setTimeout and re-send the request.

function poll() {
  var delay = 1000,
    failnum = 0;
  $.ajax({
    url: /myurl, 
        success: function(data){ 
            / / do stuff
  },
  dataType: "json",
  complete: poll,
  error: function (jqXHR, exception) {
    if (jqXHR.status === 0) {
      $("#ajax-msg").html("Not connect.\n Verify Network.");
    } else if (jqXHR.status == 404) {
      $("#ajax-msg").html("Requested page not found. [404]");
    } else if (jqXHR.status == 500) {
      $("#ajax-msg").html("Internal Server Error [500]");
    } else if (exception === 'parsererror') {
      $("#ajax-msg").html("Requested JSON parse failed.");
    } else if (exception === 'timeout') {
      $("#ajax-msg").html("Time out error.");
    } else if (exception === 'abort') {
      $("#ajax-msg").html("Ajax request aborted.");
    } else {
      $("#ajax-msg").html("Uncaught Error.\n" + jqXHR.responseText);
    }
    //wait for some interval and then try to poll again
    var opts = this;
    failnum++;
    setTimeout(function () {
      $.ajax(opts);
    }, failnum * delay * 2);
  },
  timeout: 10000
  });
}

you can of course modify failnum * delay * 2 to get the delays you want for each time it fails.

Kevin B
  • 94,570
  • 16
  • 163
  • 180
  • So to make sure I am understanding this right, this code states in the error loop, do "$.ajax(opts);" in "failnum * delay * 2" ms? where "$.ajax(opts);" = my entire poll function? – user1988318 Jan 17 '13 at 20:58
  • correct. you could simply call poll again, but that wouldn't give you as much control over the amount of delay that happens. – Kevin B Jan 17 '13 at 21:08
0

A recursive poll call after a delay would work:

function poll(delay){ 
   ...
        error: function(jqXHR, exception) {
            ...
            //wait for some interval and then try to poll again
            setTimeout(function() {
                poll(delay ? 2 * delay : 1000);
            }, 
            delay ? delay : 1000);
         },
         timeout: 10000 
    });
}

But this will never stop trying until you turn off the browser or computer. But that's what you asked for.

BenMorel
  • 34,448
  • 50
  • 182
  • 322
Lee Meador
  • 12,829
  • 2
  • 36
  • 42
0

I think the easiest approach is to use the same mechanism for a continuing the poll under both success and error conditions.

Something like this should do it:

function poll(){
    clearTimeout(poll.data.timeout);
    $.ajax({ url: /myurl, 
        success: function(data){ 
            //do stuff
            poll.data.index = 0;
        }, 
        dataType: "json", 
        error: function(jqXHR, exception) {
            if (jqXHR.status === 0) {
                $("#ajax-msg").html("Not connect.\n Verify Network.");
            } else if (jqXHR.status == 404) {
                $("#ajax-msg").html("Requested page not found. [404]");
            } else if (jqXHR.status == 500) {
                $("#ajax-msg").html("Internal Server Error [500]");
            } else if (exception === 'parsererror') {
                $("#ajax-msg").html("Requested JSON parse failed.");
            } else if (exception === 'timeout') {
                $("#ajax-msg").html("Time out error.");
            } else if (exception === 'abort') {
                $("#ajax-msg").html("Ajax request aborted.");
            } else {
                $("#ajax-msg").html("Uncaught Error.\n" + jqXHR.responseText);
            }
            poll.data.index = Math.min(++poll.data.index, poll.data.delays.length-1);
        },
        complete: function( jqXHR, textStatus){
            //wait for some interval and then try to poll again
            poll.data.timeout = setTimeout(poll, poll.data.delays[poll.data.index] * 1000);
        },
        timeout: 10000 
    });
}
//And now a tidy place to keep the data for managing the poll.
poll.data = {
    delays: [0, 1, 2, 4, 8, 16, 32, 60, 120, 240, 600, 1200, 1800, 2400],//seconds
    index: 0,
    timeout
};
Beetroot-Beetroot
  • 18,022
  • 3
  • 37
  • 44
  • I added an alert after "poll.data.timeout = setTimeout(poll, poll.data.delays[poll.data.index] * 1000);" For some reason poll.data.timeout is being set to 796, 798, 800, 802, 804 ... What am I missing? – user1988318 Jan 17 '13 at 22:05