title: Retry a jquery ajax request which has callbacks attached to its deferred
body: <p>I'm trying to implement a system of retrying ajax requests that fail for a temporary reason. In my case, it is about retrying requests that failed with a 401 status code because the session has expired, after calling a refresh webservice that revives the session.</p>
  
  <p>The problem is that the "done" callbacks are not called on a successful retry, unlike the "success" ajax option callback that is called. I've made up a simple example below:</p>
  
  <pre><code>$.ajaxSetup({statusCode: {
      404: function() {
          this.url = '/existent_url';
          $.ajax(this);
      }
  }});
  
  $.ajax({
      url: '/inexistent_url',
      success: function() { alert('success'); }
  })
  .done(function() {
      alert('done');
  });
  </code></pre>
  
  <p>Is there a way to have done-style callbacks called on a successful retry? I know a deferred can't be 'resolved' after it was 'rejected', is it possible to prevent the reject? Or maybe copy the doneList of the original deferred to a new deferred? I'm out of ideas:)</p>
  
  <p>A more realistic example below, where I'm trying to queue up all 401-rejected requests, and retry them after a successful call to /refresh.</p>
  
  <pre><code>var refreshRequest = null,
      waitingRequests = null;
  
  var expiredTokenHandler = function(xhr, textStatus, errorThrown) {
  
      //only the first rejected request will fire up the /refresh call
      if(!refreshRequest) {
          waitingRequests = $.Deferred();
          refreshRequest = $.ajax({
              url: '/refresh',
              success: function(data) {
                  // session refreshed, good
                  refreshRequest = null;
                  waitingRequests.resolve();
              },
              error: function(data) {
                  // session can't be saved
                  waitingRequests.reject();
                  alert('Your session has expired. Sorry.');
              }
         });
      }
  
      // put the current request into the waiting queue
      (function(request) {
          waitingRequests.done(function() {
              // retry the request
              $.ajax(request);
          });
      })(this);
  }
  
  $.ajaxSetup({statusCode: {
      401: expiredTokenHandler
  }});
  </code></pre>
  
  <p>The mechanism works, the 401-failed requests get fired a second time, the problem is their 'done' callbacks do not get called, so the applications stalls.</p>