终止带有jQuery的AJAX请求中止链

时间:2018-06-22 02:50:44

标签: ajax jquery-deferred abort

我正在进行一系列AJAX调用,如下面的示例所示,该示例在http://www.dotnetcurry.com/jquery/1022/jquery-ajax-deferred-promises上找到。

如果功能A 中AJAX调用的响应是一个空的JSON对象数组(即“ [[ ]“)?理想情况下,我不仅要中止AJAX调用链,还要通知用户未找到结果。

谢谢!

function A() {
    writeMessage("Calling Function A");
    return $.ajax({
        url: "/scripts/S9/1.json",
        type: "GET",                    
        dataType: "json"
    });
}


function B(resultFromA) {
    writeMessage("In Function B. Result From A = " + resultFromA.data);
    return $.ajax({
        url: "/scripts/S9/2.json",
        type: "GET",
        dataType: "json"
    });
}


function C(resultFromB) {
    writeMessage("In Function C. Result From B =  " + resultFromB.data);
    return $.ajax({
        url: "/scripts/S9/3.json",
        type: "GET",
        dataType: "json"
    });
}

function D(resultFromC) {
    writeMessage("In Function D. Result From C = " + resultFromC.data);
}

A().then(B).then(C).then(D);

function writeMessage(msg) {
    $("#para").append(msg + "<br>");                 
}

1 个答案:

答案 0 :(得分:1)

通常,您可以使您的每个辅助函数A,B,C,D返回一个包含响应数据的对象,以及是否希望继续调用链中的下一个函数(无论如何)。像这样:

function A(input) {
    return $.get("/scripts/S9/1.json").then(function (response) {
        return {
            continue: response.data && response.data.length,
            data: response
        };
    });
}

现在,您可以通过减少一组辅助函数,并在每个步骤中确定是否要继续(在这种情况下,您要执行下一个辅助工作者)(在此情况下,您只需继续返回最后一个有效值)来做出承诺链其余部分的结果)。由于缺少更好的名称,我已将此逻辑包装到函数breakableChain中。

function maybe() { return Math.random() > 0.25; }
function A(input) { console.log('in A:', input.data); return {continue: maybe(), data: 'result from A'}; } 
function B(input) { console.log('in B:', input.data); return {continue: maybe(), data: 'result from B'}; } 
function C(input) { console.log('in C:', input.data); return {continue: maybe(), data: 'result from C'}; } 
function D(input) { console.log('in D:', input.data); return {continue: maybe(), data: 'result from D'}; } 

function breakableChain(workers, init) {
    return workers.reduce(function (current, next) {
        return current.then(function (result) {
            return result.continue ? next(result) : result;
        });
    }, $.Deferred().resolve({continue: true, data: init}));
}

breakableChain([A, B, C, D], 'initial data').then(function (result) {
    console.log('overall:', result.data);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

当然,您可以制作一个不需要continue标志的非通用版本,而是将关于每个结果的假设直接硬编码到{{ 1}}。这样会更短一些,但不能重复使用。

整个if只是一个约定。您的约定也可能是“如果先前的调用返回了任何东西,然后继续,否则停止”,方法将是相同的,但是将不可能返回总体结果。