ajax 自动重试,什么是重试使用jQuery失败AJAX请求的最佳方式?什么是重试使用jQuery失败AJAX请求的最...

郑乐池
2023-12-01

伪代码:

$(document).ajaxError(function(e, xhr, options, error) {

xhr.retry()

})

更妙的是某种指数退避

Answer 1:

事情是这样的:

$.ajax({

url : 'someurl',

type : 'POST',

data : ....,

tryCount : 0,

retryLimit : 3,

success : function(json) {

//do something

},

error : function(xhr, textStatus, errorThrown ) {

if (textStatus == 'timeout') {

this.tryCount++;

if (this.tryCount <= this.retryLimit) {

//try again

$.ajax(this);

return;

}

return;

}

if (xhr.status == 500) {

//handle error

} else {

//handle error

}

}

});

Answer 2:

一种方法是使用包装函数:

(function runAjax(retries, delay){

delay = delay || 1000;

$.ajax({

type : 'GET',

url : '',

dataType : 'json',

contentType : 'application/json'

})

.fail(function(){

console.log(retries); // prrint retry count

retries > 0 && setTimeout(function(){

runAjax(--retries);

},delay);

})

})(3, 100);

另一种方法是使用一个retries的财产$.ajax

// define ajax settings

var ajaxSettings = {

type : 'GET',

url : '',

dataType : 'json',

contentType : 'application/json',

retries : 3 //

};

// run initial ajax

$.ajax(ajaxSettings).fail(onFail)

// on fail, retry by creating a new Ajax deferred

function onFail(){

if( ajaxSettings.retries-- > 0 )

setTimeout(function(){

$.ajax(ajaxSettings).fail(onFail);

}, 1000);

}

另一种方法( GIST ) -覆盖原来的$.ajax (更好的为DRY)

// enhance the original "$.ajax" with a retry mechanism

$.ajax = (($oldAjax) => {

// on fail, retry by creating a new Ajax deferred

function check(a,b,c){

var shouldRetry = b != 'success' && b != 'parsererror';

if( shouldRetry && --this.retries > 0 )

setTimeout(() => { $.ajax(this) }, this.retryInterval || 100);

}

return settings => $oldAjax(settings).always(check)

})($.ajax);

// now we can use the "retries" property if we need to retry on fail

$.ajax({

type : 'GET',

url : 'http://www.whatever123.gov',

timeout : 2000,

retries : 3, //

retryInterval : 2000 //

})

// Problem: "fail" will only be called once, and not for each retry

.fail(()=>{

console.log('failed')

});

一个点要考虑的是确保在$.ajax法尚未以前包装,以避免两次运行相同的代码。

您可以复制,粘贴这些片段(AS-IS)控制台对它们进行测试

Answer 3:

我已经有很多成功的用下面这段代码(例如: http://jsfiddle.net/uZSFK/ )

$.ajaxSetup({

timeout: 3000,

retryAfter:7000

});

function func( param ){

$.ajax( 'http://www.example.com/' )

.success( function() {

console.log( 'Ajax request worked' );

})

.error(function() {

console.log( 'Ajax request failed...' );

setTimeout ( function(){ func( param ) }, $.ajaxSetup().retryAfter );

});

}

Answer 4:

下面是这个小插件:

https://github.com/execjosh/jquery-ajax-retry

自动递增超时将是一个很好的补充它。

要使用它在全球刚刚与阿贾克斯$签名创建自己的功能,使用有重试API,并通过更换新的功能您所有的$就调用。

您也可以直接替换$阿贾克斯,但你无法不重试进行XHR调用即可。

Answer 5:

下面是为我工作的库异步加载的方法:

var jqOnError = function(xhr, textStatus, errorThrown ) {

if (typeof this.tryCount !== "number") {

this.tryCount = 1;

}

if (textStatus === 'timeout') {

if (this.tryCount < 3) { /* hardcoded number */

this.tryCount++;

//try again

$.ajax(this);

return;

}

return;

}

if (xhr.status === 500) {

//handle error

} else {

//handle error

}

};

jQuery.loadScript = function (name, url, callback) {

if(jQuery[name]){

callback;

} else {

jQuery.ajax({

name: name,

url: url,

dataType: 'script',

success: callback,

async: true,

timeout: 5000, /* hardcoded number (5 sec) */

error : jqOnError

});

}

}

然后,只需调用.load_script从您的应用程序和巢您的成功回调:

$.loadScript('maps', '//maps.google.com/maps/api/js?v=3.23&libraries=geometry&libraries=places&language=&hl=&region=', function(){

initialize_map();

loadListeners();

});

Answer 6:

DemoUsers的答案不工作的Zepto,因为这在误差函数指向窗口。 (以及使用这种方式“这个”不够安全,你不知道他们是如何实现Ajax或没有必要。)

对于的Zepto,也许你可以试试下面,到现在它很适合我:

var AjaxRetry = function(retryLimit) {

this.retryLimit = typeof retryLimit === 'number' ? retryLimit : 0;

this.tryCount = 0;

this.params = null;

};

AjaxRetry.prototype.request = function(params, errorCallback) {

this.tryCount = 0;

var self = this;

params.error = function(xhr, textStatus, error) {

if (textStatus === 'timeout') {

self.tryCount ++;

if (self.tryCount <= self.retryLimit) {

$.ajax(self.params)

return;

}

}

errorCallback && errorCallback(xhr, textStatus, error);

};

this.params = params;

$.ajax(this.params);

};

//send an ajax request

new AjaxRetry(2).request(params, function(){});

使用构造函数来确保请求折返!

Answer 7:

这些答案都不对工作,如果有人打电话.done()的Ajax调用之后,因为你不会有成功的方法来连接到未来的回电。 所以,如果有人做到这一点:

$.ajax({...someoptions...}).done(mySuccessFunc);

然后mySuccessFunc不会得到所谓的重试。 这里是我的解决方案,这在很大程度上来自@ cjpak的答案借这里 。 在我来说,我希望在AWS的API网关与502错误响应重试。

const RETRY_WAIT = [10 * 1000, 5 * 1000, 2 * 1000];

// This is what tells JQuery to retry $.ajax requests

// Ideas for this borrowed from https://stackoverflow.com/a/12446363/491553

$.ajaxPrefilter(function(opts, originalOpts, jqXHR) {

if(opts.retryCount === undefined) {

opts.retryCount = 3;

}

// Our own deferred object to handle done/fail callbacks

let dfd = $.Deferred();

// If the request works, return normally

jqXHR.done(dfd.resolve);

// If the request fails, retry a few times, yet still resolve

jqXHR.fail((xhr, textStatus, errorThrown) => {

console.log("Caught error: " + JSON.stringify(xhr) + ", textStatus: " + textStatus + ", errorThrown: " + errorThrown);

if (xhr && xhr.readyState === 0 && xhr.status === 0 && xhr.statusText === "error") {

// API Gateway gave up. Let's retry.

if (opts.retryCount-- > 0) {

let retryWait = RETRY_WAIT[opts.retryCount];

console.log("Retrying after waiting " + retryWait + " ms...");

setTimeout(() => {

// Retry with a copied originalOpts with retryCount.

let newOpts = $.extend({}, originalOpts, {

retryCount: opts.retryCount

});

$.ajax(newOpts).done(dfd.resolve);

}, retryWait);

} else {

alert("Cannot reach the server. Please check your internet connection and then try again.");

}

} else {

defaultFailFunction(xhr, textStatus, errorThrown); // or you could call dfd.reject if your users call $.ajax().fail()

}

});

// NOW override the jqXHR's promise functions with our deferred

return dfd.promise(jqXHR);

});

该代码段将回退和2秒,然后5秒,然后在10秒,这可以通过修改RETRY_WAIT恒定编辑后重试。

AWS支持建议我们添加一个重试,因为它在一个蓝色的月亮恰好为我们只有一次。

文章来源: What's the best way to retry an AJAX request on failure using jQuery?

 类似资料: