我所有的ajax调用都在一个自定义JS文件中。相信我,有很多!我想在所有 ajax 调用中实现"失败行为重试"。
有没有办法像"拦截"一样做到这一点?还是我必须一个接一个地做?
我在这里担心未来的开发人员会忘记设置重试策略......
示例 ajax 调用:
$.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);
}
}
});
您可以使用ajaxError
,它接受在每个 ajax 错误时调用的回调。此外,您可以向设置对象添加一个布尔值,并在回调中检查它,以确保只调用第二次而不是多次失败的请求。
$(document).ajaxError(function (event, jqxhr, settings) {
if(!settings.secondExec) {
settings.secondExec = true;
$.ajax(settings);
}
});
如果需要,请为第二个请求添加超时,以增加在此期间解决随机服务器或连接问题的可能性:
setTimeout(function() {
$.ajax(settings);
}, 500);
如果要排除某些请求,只需将另一个属性添加到请求设置中,然后使用secondExec
就像示例中使用的那样。
这是一个有效的jsfiddle。
我会这样做,使用递归函数:
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;
}
}
然后用法是这样的:
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 的开发人员可以附加他的处理程序,而无需担心要附加哪些处理程序。
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);