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

时间:2014-04-02 19:51:30

标签: javascript jquery ajax

我在自定义JS文件中拥有所有ajax调用。相信我有很多他们! 我想在所有ajax调用中实现"retry on fail behavior"

有没有办法像“拦截”那样做?或者我必须一个接一个地做?

我担心的是,未来的开发人员会忘记制定重试政策......

示例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);
        }
    }
});

3 个答案:

答案 0 :(得分:5)

您可以使用ajaxError进行每次ajax错误调用的回调。 此外,您可以在设置对象中添加一个布尔值,并在回调中检查它,以确保只有第二次调用一个失败的请求而不是更多。

$(document).ajaxError(function (event, jqxhr, settings) {
    if(!settings.secondExec) {
        settings.secondExec = true;
        $.ajax(settings); 
    }
});

如果需要,请为第二个请求添加超时,以增加同时解决随机服务器或连接问题的可能性:

setTimeout(function() {
    $.ajax(settings); 
}, 500);

如果您要排除某些请求,只需在请求设置中添加另一个属性,然后在示例中使用secondExec之类的{{1>}。

答案 1 :(得分:4)

您可以为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);

答案 2 :(得分:4)

这是working 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.");
    });