配置 jQuery 以在 ajax 调用失败时重试



我所有的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);

最新更新