admin管理员组

文章数量:1244330

I have all my ajax calls in a custom JS file. And trust me there are alot of them! I would like to implement a "retry on fail behavior" in all ajax calls.

Is there a way to do it like "interception"? Or do I have to do it one by one?

My fear here is that a future dev will forget to set the retry policy...

Sample ajax call:

$.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);
        }
    }
});

I have all my ajax calls in a custom JS file. And trust me there are alot of them! I would like to implement a "retry on fail behavior" in all ajax calls.

Is there a way to do it like "interception"? Or do I have to do it one by one?

My fear here is that a future dev will forget to set the retry policy...

Sample ajax call:

$.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);
        }
    }
});
Share Improve this question edited May 23, 2017 at 12:09 CommunityBot 11 silver badge asked Apr 2, 2014 at 19:51 LeonardoLeonardo 11.4k13 gold badges72 silver badges182 bronze badges 6
  • 1 some info on why the down-vote/close would be nice... – Leonardo Commented Apr 2, 2014 at 20:05
  • Not the downvoter but it would be helpful if you could add an example of how your average ajax call looks like. – Marcel Gwerder Commented Apr 2, 2014 at 20:10
  • 1 Don't use $.ajax. Provide your own set of APIs which wrap around it. – user229044 Commented Apr 2, 2014 at 20:22
  • 1) onSuccess and onError check fails when variable does not exist. To make it more stable use window.onSuccess and window.onError instead. 2) Program in english so we ALL understand what you try to do. 3) It is not clear EXACTLY what you mean or try to do. – Codebeat Commented Apr 2, 2014 at 21:28
  • possible duplicate of How do I resend a failed ajax request? – user2284570 Commented Oct 10, 2014 at 18:59
 |  Show 1 more ment

3 Answers 3

Reset to default 6

You can use ajaxError which takes a callback that is called on every ajax error. Additionally you can add a boolean to the settings object and check for it in the callback which ensures that one failed request is only called a second time and not more.

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

If desired add a timeout for the second request to increase the possibility that a random server or connection problem is resolved in the meantime:

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

If you want to exclude some requests just add another property to the request settings which you then use like secondExec is used in the example.

Here's a working jsfiddle.

I'd do it like this, with a recursive function:

function AjaxRetry(settings, maxTries, interval) {
    var self = this;
    this.settings = settings;
    this.maxTries = typeof maxTries === "number" ? maxTries : 0;
    this.pletedTries = 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.pletedTries + 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.pletedTries++;

                // Recursively call this function again (after a timeout)
                // until either it succeeds or we hit the max number of tries
                if (self.pletedTries < self.maxTries) {
                    console.log("Waiting " + interval + "ms before retrying...");
                    setTimeout(function(){
                        tryAjax(d);
                    }, self.interval);
                } else {
                    d.reject(error);
                }
            });
        return d;
    }
}

And then usage is like this:

 var settings = {
     url: "https://httpbin/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.");
    });

You can create api method for ajax calls, just like this one. In the ajaxApi function you can create your own handlers. For example for success or error events, thanks to this developer using this api can attach his handlers, without worrying what else handlers to attach.

function outerSuccesFN() {
    console.log('outerSuccesFN');
}

function outerErroFN() {
    console.log('outerErroFN');
}

function pleteFn() {
    console.log(pleteFn);
}

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./jsonp/', 'jsonp', {
    title: 'ajax'
}, 15000);

ajaxResult.done(outerSuccesFN).fail(outerErroFN).always(pleteFn);

本文标签: javascriptConfigure jQuery to retry ajax calls if they failStack Overflow