我在jQuery中使用ajax,我们知道$.ajax
会返回一个promise ajaxPromise
。我的要求是:只有当所有ajax调用重试失败时,ajaxPromise
才能捕获失败(我想在ajax promise回调函数中处理错误)。
我尝试了以下代码:
function ajax(data) {
return $.ajax({
url: "...",
data: data,
triedCount: 0,
retryLimit: 3,
error: function(xhr, textStatus, errorThrown ) {
console.log("error: " + this.triedCount);
this.triedCount++;
if (this.triedCount < this.retryLimit) {
$.ajax(this);
}
}
});
}
var ajaxPromise = ajax({"id": "123"});
ajaxPromise.fail(function(xhr) {
console.log("All retries failed...");
// all retries failed, handle error
});
输出我想要的是:
error: 0
error: 1
error: 2
All retries failed...
实际上输出是:
error: 0
All retries failed...
error: 1
error: 2
看起来第一次调用失败后会立即触发fail
回调,而我希望在所有重试失败后触发fail
回调。
有没有办法只有当所有重试失败然后触发ajaxPromise.fail
回调?或者还有其他选择可以做到吗?
答案 0 :(得分:1)
var g = $('#<%=lblStatus.ClientID%>').html();
在你的代码中,如果发生错误,你正在调用ajax函数。但这并不意味着之前的ajax调用没有完成。第一个ajax调用完成并发送返回值(失败)。你的
function ajax(data) {
return $.ajax({
url: "...",
data: data,
triedCount: 0,
retryLimit: 3,
error: function(xhr, textStatus, errorThrown ) {
console.log("error: " + this.triedCount);
this.triedCount++;
if (this.triedCount < this.retryLimit) {
console.log(this);
$.ajax(this);
}
}
});
}
运行,并且您将获得“所有重试失败...”登录到控制台。 如果你想实现你想要实现的目标,你必须拦截以前的结果并防止它被返回。相反,检查3次尝试是否已完成,然后返回该值。但我不知道该怎么做。
编辑 :经过长时间的研究,我发现这是不可能的。你应该放弃尝试做这样的事情......开个玩笑!检查这段代码,我相信这正是你想要的:
ajaxPromise.fail(function(xhr) {
console.log("All retries failed...");
// all retries failed, handle error
});
// Code goes here
function ajax(data) {
var dfd = $.Deferred();
$.ajax({
url: "...",
data: data,
triedCount: 0,
retryLimit: 3,
success: function(){
dfd.resolve("success");
},
error: function(xhr, textStatus, errorThrown ) {
console.log("error: " + this.triedCount);
this.triedCount++;
if (this.triedCount < this.retryLimit) {
$.ajax(this);
}
else{
dfd.reject(xhr);
}
}
});
return dfd.promise();
}
var ajaxPromise = ajax({"id": "123"});
ajaxPromise.fail(function(xhr) {
console.log("All retries failed...");
// all retries failed, handle error
console.log(xhr.responseText);
});
编辑:失败的ajax调用引发的错误将在<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
回调的xhr
参数中提供。
答案 1 :(得分:1)
您可以使用$.Deferred()
,.rejectWith()
;使用beforeStart
$.Deferred()
调用递归函数,并将ajaxOptions
作为参数传递;如果this.triedCount
不小于this.retryLimit
,则返回被拒绝的延迟对象,其中this
设置为当前ajax选项,xhr
作为参数传递给.fail()
链接到{{ 1}}
ajaxPromise
function ajax(data) {
var ajaxOptions = {
url: "...",
data: data,
triedCount: 0,
retryLimit: 3
};
return new $.Deferred(function(dfd) {
function request(opts) {
$.ajax(opts)
.fail(function(xhr, textStatus, errorThrown) {
console.log("error: " + this.triedCount);
this.triedCount++;
if (this.triedCount < this.retryLimit) {
return request(this)
} else {
dfd.rejectWith(this, [xhr])
}
})
}
request(ajaxOptions)
})
}
var ajaxPromise = ajax({
"id": "123"
});
ajaxPromise.fail(function(xhr) {
console.log("All retries failed...", xhr);
// all retries failed, handle error
});