我正在使用以下代码来生成多个这样的ajax请求:
请求 1开始 |要求 1完成 |请求 2开始 |要求 2完成 | ...
这是代码:
var startingpoint = fireRequest(1);
$.each(types,function(ix,type)
{
startingpoint = startingpoint.pipe( function()
{
alert(startingpoint.status); // undefined
return fireRequest(type);
});
});
fireRequest 只是一个正确的ajax函数的switchcase,它返回$ .ajax(...)
当一个请求失败时,我希望链停止。我开始实现它并作为测试我想提醒ajax对象的状态,但它显示'undefined'。我怎样才能获得状态?
答案 0 :(得分:1)
您尝试实现的行为已经是.pipe()方法的行为。它需要两个回调作为参数,并且只会执行完成回调并在前一个请求成功时沿着链继续。这可以在下面的jsfiddle中说明: http://jsfiddle.net/dflor003/Vq2YF/(注意:在具有内置JSON.stringify支持和console.log支持的浏览器中打开它)
如果您确实想要检查请求的状态,它将把状态作为完成回调的第二个参数。更多细节可以在jQuery的API文档站点上找到:http://api.jquery.com/deferred.pipe/
答案 1 :(得分:0)
此代码假定您希望在任何一个请求失败时(通过404或500响应或超时)中止其他请求,并且不需要评估数据响应以确定业务逻辑故障情形。 $.when()
该方法将尽快解决其主延迟 延迟解决,或拒绝主人延期一个 延期被拒绝。
$.when(fireRequest(1), fireRequest(2),fireRequest(3))
.then(myAllSuccessfulFunc, oneFailedFunc);
function myAllSuccesfulFunc(req1,req2,req3){
//everything returned a 200.
alert("these are not the droids you are looking for");
};
function oneFailedFunc(req1,req2,req3){
//* each req looks like [ "not success", statusText, jqXHR ] */
//feel free to check what failed, but I don't know what you need
req1[2].abort();
req2[2].abort();
req3[2].abort();
};
您实际上需要在响应中解析成功的数据请求,以查看是否由于后端的逻辑而导致其他请求失败。
var stop = 4;
//if you are sure fireRequest(x) returns a good promise object, do this:
callNext(fireRequest(1),1);
function callNext(promise, currentIndex){
promise.done(function(ajaxArgs){
var jqXHR = ajaxArgs[2];
//replace this with some logic check that makes sense to your app
if(/error/.test(jqXHR.responseText)){
//do something
}else if(currentIndex <stop){
callNext(fireRequest(currentIndex+1),currentIndex+1);
}).fail(function(ajaxArgs){
//server returned a 404, or a 500, or something not a success.
});
};
答案 2 :(得分:0)
我认为问题在于$.Deferred
和类似的设计用于处理异步和并发过程,所以如果你想让它们按照你描述的方式行事,你总是必须以某种方式欺骗它们。 / p>
如果你想/需要一个接一个地处理你的调用(使用 A JAX)我建议将它们放入一个数组并使用一个简单的递归函数循环遍历该数组直到所有呼叫完成或其中一个失败。
这基本上就像:
var requests = [
{
url : '/serviceA'
data : myParams4ServiceA
},
...
{
url : '/serviceZ'
data : myParams4ServiceZ
}
];
既然你有一个AJAX请求数组,你可以构建一个递归函数,逐个解决它们:
function work(){
$.ajax(requests[0]).done(function(data){
//handle data here
requests.shift(); //request is done and can be removed from the Array, request[0] will now be the next request in the queue
if (requests.length){
work(); //function calls itself again if there's still need for it
} else {
// we are done!
}
}).fail(function(e){
//call failed -> handle error
});
}
work();
有关成功链的示例,请参见 this fiddle ,对于失败的链,请参见 this one 。
另一种可能性是将AJAX调用设置为async : false
(请注意,这在jQuery 1.8+中已弃用:“从jQuery 1.8开始,使用async:false和jqXHR($ .Deferred)已弃用;您必须使用完整/成功/错误回调。“这将再次指向我们”,并使用您应用于您的请求数组的简单$.when().then().fail()
链:
$.when.apply($, requests).then(function(){
$.each(arguments, function(){
//do stuff with your data
});
}).fail(function(){
//handle the error
});
由于您的通话现在正在阻止,因此这也将连续处理它们。请参阅 a fiddle 。