2013-06-27 92 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

可能的[使用jQuery失败时重试AJAX请求的最佳方式是什么?](http ://stackoverflow.com/questions/10024469/whats-the-best-way-to-retry-an-ajax-request-on-failure-using-jquery) – user2284570

回答

3

我认为你的代码是正确的做法,将你的调用包装在一个新的Deferred中并返回,直到达到所有的尝试。

您可以尝试将您的递归调用包含在匿名函数中以提高可读性。

我写的那样:

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的回答和周围SO dherman创造了一个jQuery插件其他几个:jquery.ajaxRetryGitHub repo)等具有johnkpauljquery.ajax-retry

jquery.ajaxRetry

$.ajax({ 
    // Retry this request up to 2 times 
    shouldRetry: 2 
}); 
  • Can retry indef initely
  • 可以重试n
  • 能在shouldRetry运行功能和评价truefalse,以确定它是否应该继续重试

jQuery的。Ajax的重试

$.ajax(options).retry({times:3, timeout:3000}).then(function(){ 
    alert("success!"); 
    }); 
  • 可以重试n
  • 可以指定时间重试之间等待量
  • 可以指定重试什么状态代码为