Configure jQuery to retry ajax calls if they fail
我在自定义JS文件中拥有所有的ajax调用。 相信我有很多他们!
我想在所有ajax调用中实现"重试失败行为"。
有没有办法像"拦截"那样做? 或者我必须一个接一个地做?
我担心的是,未来的开发者将忘记制定重试政策......
示例ajax调用:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | $.ajax({ url: apiRoot + 'reservationItens?reservaId=' + idReservation + '&bagId=' + idBag, type: 'PUT', success: function () { if (onSuccess != null) { onSuccess(); } }, error: function (x, y, z) { if (onError != null) { onError(x, y, z); } } }); |
您可以使用
此外,您可以向设置对象添加一个布尔值,并在回调中检查它,以确保一个失败的请求仅被第二次调用而不是更多。
1 2 3 4 5 6 | $(document).ajaxError(function (event, jqxhr, settings) { if(!settings.secondExec) { settings.secondExec = true; $.ajax(settings); } }); |
如果需要,为第二个请求添加超时,以增加同时解决随机服务器或连接问题的可能性:
1 2 3 | setTimeout(function() { $.ajax(settings); }, 500); |
如果要排除某些请求,只需将另一个属性添加到请求设置中,然后在示例中使用
这是一个有效的jsfiddle。
我会这样做,具有递归功能:
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 | function AjaxRetry(settings, maxTries, interval) { var self = this; this.settings = settings; this.maxTries = typeof maxTries ==="number" ? maxTries : 0; this.completedTries = 0; this.interval = typeof interval ==="number" ? interval : 0; // Return a promise, so that you can chain methods // as you would with regular jQuery ajax calls return tryAjax().promise(); function tryAjax(deferred) { console.log("Trying ajax #" + (self.completedTries + 1)); var d = deferred || $.Deferred(); $.ajax(self.settings) .done(function(data) { // If it succeeds, don't keep retrying d.resolve(data); }) .fail(function(error) { self.completedTries++; // Recursively call this function again (after a timeout) // until either it succeeds or we hit the max number of tries if (self.completedTries < self.maxTries) { console.log("Waiting" + interval +"ms before retrying..."); setTimeout(function(){ tryAjax(d); }, self.interval); } else { d.reject(error); } }); return d; } } |
然后使用是这样的:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | var settings = { url:"https://httpbin.org/get", data: {foo:"bar"}, contentType:"application/json; charset=UTF-8" }; var maxTries = 3; var interval = 500; // Make your ajax call and retry up to 3 times, // waiting 500 milliseconds between attempts. new AjaxRetry(settings, maxTries, interval) .done(function(data){ alert("My ajax call succeeded!"); }) .fail(function(error) { alert("My ajax call failed :'("); }) .always(function(resp){ alert("My ajax call is over."); }); |
您可以为ajax调用创建api方法,就像这个一样。在ajaxApi函数中,您可以创建自己的处理程序。例如,对于成功或错误事件,感谢这个开发人员使用这个api可以附加他的处理程序,而不用担心附加什么处理程序。
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 | function outerSuccesFN() { console.log('outerSuccesFN'); } function outerErroFN() { console.log('outerErroFN'); } function completeFn() { console.log(completeFn); } function ajaxApi(url, dataType, data, timeout) { var ajaxResults = $.ajax({ url: url, dataType: dataType, data: data, timeout: timeout }); function mySuccesFn() { console.log('mySuccesFn'); } function myErroFn() { console.log('myErroFn'); } return ajaxResults.done(mySuccesFn).fail(myErroFn); } var ajaxResult = ajaxApi('http://api.jquery.com/jsonp/', 'jsonp', { title: 'ajax' }, 15000); ajaxResult.done(outerSuccesFN).fail(outerErroFN).always(completeFn); |