2014-04-25 3 views
0

J'utilise un préfiltre pour refaire la requête ajax 2 fois max, voir code ci-dessous.Retry ajax request after timeout

Cependant, le problème est que le gestionnaire original fail() de la requête ajax est également appelé. Cela doit être désactivé bien sûr.

$.ajaxPrefilter(function(options, originalOptions, jqXHR) { 
    // retry not set or less than 2 : retry not requested 
    if (!originalOptions.retryMax || !originalOptions.retryMax >= 2) { 
     return; 
    } 
    // no timeout was setup 
    if (!originalOptions.timeout > 0) { 
     return; 
    } 

    if (originalOptions.retryCount) { 
     originalOptions.retryCount++; 
    } else { 
     originalOptions.retryCount = 1; 
     // save the original error callback for later 
     if (originalOptions.error) { 
      originalOptions._error = originalOptions.error; 
     } 
    }; 

    // overwrite *current request* error callback 
    options.error = $.noop(); 

    // setup our own deferred object to also support promises that are only invoked 
    // once all of the retry attempts have been exhausted 
    var dfd = $.Deferred(); 

    jqXHR.done(dfd.resolve); 

    // if the request fails, do something else yet still resolve 
    jqXHR.fail(function() { 
     var args = Array.prototype.slice.call(arguments); 

     if (originalOptions.retryCount >= originalOptions.retryMax || jqXHR.statusText !== "timeout") { 
      // add our _error callback to our promise object 
      if (originalOptions._error) { 
       dfd.fail(originalOptions._error); 
      } 
      dfd.rejectWith(jqXHR, args); 
     } else { 
      $.ajax(originalOptions).then(dfd.resolve, dfd.reject); 
     } 
    }); 
}); 

Ma demande est: Et je reçois le message console.log « nous sommes en échec » en même temps que la demande est refait à neuf pour la première fois. Une idée de comment résoudre ce problème?

 $.ajax({ 
     url: url, 
     crossDomain: true, 
     dataType: "json", 
     type: type, 
     timeout: 20000, 
     async: (async === undefined ? true : async), 
     beforeSend: beforeSend, 
     retryMax: (type == "POST" ? 0 : 2), 
     data: data 
    }).done(function(response, status, xhr) { 
      }).fail(function(xhr, textStatus, error) { 
     console.log("WE ARE IN FAIL"); 
    }); 

Répondre

0

moyen plus facile (désolé, je n'ai que le temps d'écrire du code partiel) :(

Créer une fonction récursive qui gère la demande ajax et prend des paramètres + un compteur.

var MyFuncAjax = function(params, counter){ 
    if(counter <= 0){ return true; } 

    $ajax({ 
    ... 
    timeout: params.timeout 
    ... 
    }) 
    ...fail(function(xhr...){ 
    MyFuncAjax(params, --counter) 
    }) 
} 

ensuite, appelez il

MyFuncAjax({timeout: 20000, ....}, 2) 

Et le tour est joué :)