Javascript jQuery延迟链失败的继续

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

我在jQuery中进行了一系列连续的AJAX调用,使用了与Deferred链接的常用方法。第一个调用返回一个值列表,后续调用使用这些返回的列表项进行。在返回列表的第一个调用之后,后续调用可以按任何顺序执行,但必须一次执行一个。这就是我使用的:

$.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()
    必须至少接受一个参数。假定它接受
    errorshown
    ,但可能同样接受jqXHR或textStatus

  • 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);
        });
    }