关于javascript:网络中断后重试功能

Retry function after network outage

给出以下jQuery代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
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.
 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.
"
+ jqXHR.responseText);
            }
            //wait for some interval and then try to poll again
         },
         timeout: 10000
    });
}

在错误条件下,我希望在1s,2s,4s,8s,16s,32s,1m,2m,4m,10m,20m,30m,40m中再次调用poll()函数...

我已经读过使用睡眠不正确。 我想知道正确的"睡眠"方式,设置间隔或超时来实现这一目标。


只需使用setTimeout并重新发送请求即可。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
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.
 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.
"
+ 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
  });
}

您当然可以修改failnum * delay * 2以获得每次失败时所需的延迟。


我认为最简单的方法是在成功和错误条件下使用相同的机制继续进行调查。

这样的事情应该这样做:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
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.
 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.
"
+ 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
};


延迟后的递归轮询调用将起作用:

1
2
3
4
5
6
7
8
9
10
11
12
13
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
    });
}

但是,在关闭浏览器或计算机之前,这将永远不会停止尝试。 但这就是你要求的。