ajax failed啥意思,javascript - 使用jQuery在失败时重试AJAX请求的最佳方法是什么?...

javascript - 使用jQuery在失败时重试AJAX请求的最佳方法是什么?

伪代码:

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

xhr.retry()

})

更好的是某种指数回退

7个解决方案

204 votes

像这样的东西:

$.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

}

}

});

Sudhir Bastakoti answered 2019-08-26T12:36:29Z

8 votes

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

(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);

另一种方法是在$.ajax上使用$.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方法,以避免相同的代码运行两次。

您可以将这些片段(按原样)复制粘贴到控制台以进行测试

vsync answered 2019-08-26T12:37:23Z

4 votes

我在下面的代码中取得了很大的成功(例如:[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 );

});

}

Nabil Kadimi answered 2019-08-26T12:37:48Z

0 votes

这是一个小插件:

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

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

要在全局范围内使用它,只需使用$ .ajax签名创建自己的函数,在那里使用retry api并用新函数替换所有$ .ajax调用。

你也可以直接替换$ .ajax,但是如果没有重试,你将无法进行xhr调用。

Oleg Isonen answered 2019-08-26T12:38:49Z

0 votes

这是我用于异步加载库的方法:

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();

});

Abram answered 2019-08-26T12:39:21Z

0 votes

DemoUsers的答案不适用于Zepto,因为错误功能中的这个指向Window。 (这种使用&#39;这种方式不够安全,因为你不知道他们如何实现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(){});

使用构造函数确保请求是可重入的!

Xhua answered 2019-08-26T12:40:05Z

0 votes

如果有人在他们的ajax呼叫之后拨打mySuccessFunc,这些答案都不起作用,因为你没有成功的方法来附加到未来的回叫。 所以,如果有人这样做:

$.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支持建议我们添加重试,因为它只在蓝色月亮中发生一次。

Ryan Shillington answered 2019-08-26T12:40:54Z

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值