Javascript jQuery延迟链失败的继续
我在jQuery中进行了一系列连续的AJAX调用,使用了与Deferred链接的常用方法。第一个调用返回一个值列表,后续调用使用这些返回的列表项进行。在返回列表的第一个调用之后,后续调用可以按任何顺序执行,但必须一次执行一个。这就是我使用的:Javascript jQuery延迟链失败的继续,javascript,jquery,jquery-deferred,deferred,Javascript,Jquery,Jquery Deferred,Deferred,我在jQuery中进行了一系列连续的AJAX调用,使用了与Deferred链接的常用方法。第一个调用返回一个值列表,后续调用使用这些返回的列表项进行。在返回列表的第一个调用之后,后续调用可以按任何顺序执行,但必须一次执行一个。这就是我使用的: $.when(callWebService()).then( function (data) { var looper = $.Deferred().resolve(), myList = JSON.parse(data);
$.when(callWebService()).then(
function (data) {
var looper = $.Deferred().resolve(),
myList = JSON.parse(data);
for (var i in myList) {
(function (i) {
looper = looper.then(function () { // Success
return callWebService();
},
function (jqXHR, textStatus, errorThrown) { // Failure
if (checkIfContinuable(errorThrown) == true)
continueChain();
else
failWithTerribleError();
});
})(i);
}
});
事实证明,随后的调用有时可能会失败,但我仍然希望执行其余的调用。在我的清单中,这就是这段创造性的伪代码的目的:
if (checkIfContinuable(errorThrown) == true)
continueChain();
else
failWithTerribleError();
但我到底该如何实现continueChain?看起来,任何延迟上的故障都会导致链的其余部分也发生故障。相反,我希望记录错误并继续列表中的其余部分。使用此操作与
promise.then(…, function(err) {
if (checkIfContinuable(err))
return valueToConinueWith;
else
throw new TerribleError(err);
})
不幸的是,并转发旧值(结果或错误)——除非返回回调延迟的jQuery。其工作原理与:
从jQuery承诺链中的错误恢复比使用承诺/a+实现更详细,后者自然会捕获.catch或.then错误处理程序中的错误。您必须抛出/重新抛出以传播错误状态 jQuery的工作方式正好相反。then的错误处理程序(.catch不存在)将自然传播错误状态。要模仿“捕获”,您必须返回已确定的承诺,链将沿着其成功路径前进 从一系列异步调用所基于的项目数组开始,使用起来很方便 注:
- 假定有一个整体函数包装器,
函数getWebServiceResults(){…}
- 假定
接受callWebService()
——即项
的每个元素的内容myList
- 若要执行其工作,
必须至少接受一个参数。假定它接受checkIfContinuable()
,但可能同样接受jqXHR或textStatuserrorshown
continueChain
和failWithTerribleError
到底做了什么?请看,@CobusKruger尝试使用。always()
@josephdTeamer它们是占位符。当实现failWithTerribleError时,如果错误不可继续,则failWithTerribleError将执行任何需要执行的操作,无论是记录错误、显示警报还是其他操作。continueChain是我要问的问题-我希望下一次web服务调用能够像从未发生过故障一样进行。您知道使用.fail()
方法是否有类似的解决方案吗?我根本不需要并行成功处理程序(这里有…
),但这个答案似乎只在使用then
的2或3个参数形式时有效。我把这当作一个单独的问题问
jDeferred.then(…, function(err) {
if (checkIfContinuable(err))
return $.Deferred().resolve(valueToConinueWith);
else
return $.Deferred().reject(new TerribleError(err));
})
function getWebServiceResults() {
return callWebService().then(function(data) {
var myList;
// This is genuine Javascript try/catch, in case JSON.parse() throws.
try {
myList = JSON.parse(data);
}
catch (error) {
return $.Deferred().reject(error).promise();//must return a promise because that's what the caller expects, whatever happens.
}
//Now use `myList.reduce()` to build a promise chain from the array `myList` and the items it contains.
var promise = myList.reduce(function(promise, item) {
return promise.then(function(arr) {
return callWebService(item).then(function(result) {
arr.push(result);
return arr;
}, function(jqXHR, textStatus, errorThrown) {
if(checkIfContinuable(errorThrown)) {
return $.when(arr); // return a resolved jQuery promise to put promise chain back on the success path.
} else {
return new Error(textStatus);//Although the error state will be naturally propagated, it's generally better to pass on a single js Error object rather than the three-part jqXHR, textStatus, errorThrown set.
}
});
});
}, $.when([])) // starter promise for the reduction, resolved with an empty array
// At this point, `promise` is a promise of an array of results.
return promise.then(null, failWithTerribleError);
});
}