重试一个jquery ajax请求,该请求具有附加到其延迟的回调

前端之家收集整理的这篇文章主要介绍了重试一个jquery ajax请求,该请求具有附加到其延迟的回调前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我试图实现一个系统重试ajax请求失败的临时原因。在我的情况下,它是关于重试请求失败的401状态代码,因为会话已过期,在调用刷新webservice恢复会话后。

问题是,“done”回调不会在成功的重试上调用,与调用的“success”ajax选项回调不同。我已经做了一个简单的例子如下:

@H_403_4@$.ajaxSetup({statusCode: { 404: function() { this.url = '/existent_url'; $.ajax(this); } }}); $.ajax({ url: '/inexistent_url',success: function() { alert('success'); } }) .done(function() { alert('done'); });

有没有一种方法来完成样式的回调调用成功的重试?我知道一个推迟的人在“被拒绝”之后不能被“解决”,是否有可能防止被拒绝?或者也许复制原始延迟的doneList到新的延迟?我的想法:)

一个更现实的示例如下,其中我试图排队所有401拒绝的请求,并在成功调用/刷新后重试它们。

@H_403_4@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 }});

机制工作,401失败的请求第二次被触发,问题是他们的“完成”回调没有被调用,所以应用程序停顿。

解决方法

你可以使用 jQuery.ajaxPrefilter将jqXHR包装在另一个 deferred object

我做了一个例子,jsFiddle显示它的工作,并试图适应一些你的代码来处理401到这个版本:

@H_403_4@$.ajaxPrefilter(function(opts,originalOpts,jqXHR) { // you could pass this option in on a "retry" so that it doesn't // get all recursive on you. if (opts.refreshRequest) { return; } // our own deferred object to handle done/fail callbacks var dfd = $.Deferred(); // if the request works,return normally 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 (jqXHR.status === 401) { $.ajax({ url: '/refresh',refreshRequest: true,error: function() { // session can't be saved alert('Your session has expired. Sorry.'); // reject with the original 401 data dfd.rejectWith(jqXHR,args); },success: function() { // retry with a copied originalOpts with refreshRequest. var newOpts = $.extend({},{ refreshRequest: true }); // pass this one on to our deferred pass or fail. $.ajax(newOpts).then(dfd.resolve,dfd.reject); } }); } else { dfd.rejectWith(jqXHR,args); } }); // NOW override the jqXHR's promise functions with our deferred return dfd.promise(jqXHR); });

这是因为deferred.promise(object)实际上会覆盖jqXHR上的所有“promise方法”。

注意:任何人发现这一点,如果你附加回调成功:和错误:在ajax选项,这个片段将无法按预期的方式工作。它假定唯一的回调是使用jqXHR的.done(callback)和.fail(callback)方法附加的回调。

猜你在找的jQuery相关文章