2013-06-27 4 views
3

Мне нужно создать функцию, которая повторяет неудачный запрос ajax до указанного предела, , но Мне нужно, чтобы обещание было отклонено только в случае превышения максимального количества попыток, например:Ошибка повторения запросов jQuery.ajax

function my_ajax(...) { ... } 

// then I use it this way 
return $.when(my_ajax('foo.json'), my_ajax('bar.json')) 

для того, чтобы работать с jQuery.when, только один посыл должен быть возвращен в my_ajax, которые должны быть решены, когда внутренний jQuery.ajax разрешен, и отвергнут только тогда, когда был сделан максимум повторов.

код я сделал это:

function do_ajax(args, dfd, attempt) { 
    dfd  || (dfd = $.Deferred()); 
    attempt || (attempt = 1); 

    $.ajax(args).then(dfd.resolve, function(xhr, text_status, error_thrown) { 
     console.error(/* something useful */); 
     attempt++; 

     if(attempt > 3) { 
      dfd.reject(xhr, text_status, error_thrown); 
     } else { 
      do_ajax(args, dfd, attempt); 
     } 
    }); 

    return dfd.promise(); 
} 

// in some random code 
return $.when(do_ajax({url:'foo.json'}), do_ajax({url:'bar.json'}); 

Это работает для меня *, но это своего рода трудно понять. Вопрос в том, есть ли лучший способ (и более легкий для чтения)?

* - На самом деле я не проверял, чтобы иногда терпеть неудачу, но я отлично работаю, когда первый запрос ajax успешно завершен.

+0

возможный дубликат [Какой лучший способ повторить запрос AJAX при сбое с помощью jQuery?] (http : //stackoverflow.com/questions/10024469/whats-the-best-way-to-retry-an-ajax-request-on-failure-using-jquery) – user2284570

ответ

3

Я думаю, что ваш код - это правильный способ сделать это, заверните свой вызов в новом Отложенном и верните его, пока не будут достигнуты все попытки.

Вы можете попытаться включить свой рекурсивный вызов внутри анонимной функции, чтобы улучшить ее читаемость.

Я написал так:

function doAjax(ajaxArgs, attempt) { 
    // the wrapped returned dfd 
    var wrappedDfd = $.Deferred(); 

    // your nested call using attempt counter 
    (function nestedCall() { 
     // if call succed, resolve the wrapped dfd 
     $.ajax(ajaxArgs).then(wrappedDfd.resolve, function() { 
      // update attempt counter 
      attempt--; 
      if (attempt > 0) { 
       // try another call 
       nestedCall(); 
      } else { 
       // max try reached, reject wrapped dfd 
       wrappedDfd.reject(); 
      } 
     }); 
    })(); 

    return wrappedDfd.promise(); 
}; 

, который действительно похож на код.

Адрес jsfiddle. Для целей тестирования я заменил аргументы doAjax фабричным вызовом макета, но код остался прежним.

Надеюсь, что эта помощь.

1

На основании ответа Mordhak «s и несколько других вокруг SO dherman создал плагин JQuery: jquery.ajaxRetry (GitHub repo) и поэтому имеет johnkpaul: jquery.ajax-retry

jquery.ajaxRetry

Пример

$.ajax({ 
    // Retry this request up to 2 times 
    shouldRetry: 2 
}); 
  • Может повторять инфиф initely
  • удается повторить n раз
  • Может запустить функцию и оценить, true или false в shouldRetry, чтобы определить, должен ли он продолжать соединяться

JQuery.Ajax-повторов

Пример

$.ajax(options).retry({times:3, timeout:3000}).then(function(){ 
    alert("success!"); 
    }); 
  • удается повторить n раз
  • Можно указать количество времени ожидания между попытками
  • Можно указать, какой статус коды повторить для