jQuery done() 向下三层

jQuery done() three levels down

我有三个 ajax 调用给我数据,我将这些数据推入数组。

第二个在第一个之后调用(在它的成功函数中),这样数组就不会被异步填充。

我的目标是在最后使用 jQuery done() 函数(或类似函数)进行某种回调(在我的代码中标记为 "END!!")。然而,jQuery done() 函数在第一级已经达到它的成功函数后开始。

var ajaxQuery = $.ormon('ajax', {
    url: '../getjson',
    trtyp: 'adm1034',
    dataType: 'json',
    data: {
        clients:1
    },

    success: function(data) {
        console.log("1");

        for (i = 0; i < data.length; i++) {
            var name = data[i].adr1 + " " + data[i].adr2;
            kontaktdata.push({name: name, usrid: data[i].usr});
        }

        $.ormon('ajax', {
            url: '../getjson',
            trtyp: 'adm1034',
            dataType: 'json',
            data: {
                clients:2
            },

            success: function(data) {
                console.log("2");

                for (i = 0; i < data.length; i++) {
                    var name = "(CRM Lead) - " + data[i].adr1 + " " + data[i].adr2;
                    kontaktdata.push({name: name, usrid: data[i].usr});
                }

                $.ormon('ajax', {
                    url: '../getjson',
                    trtyp: 'adm1034',
                    dataType: 'json',
                    data: {
                        clients:3
                    },

                    success: function(data) {
                        console.log("3");
                        for(i = 0; i < data.length; i++) {
                            var name = "(MXVV Kunden) - " + data[i].adr1 + " " + data[i].adr2;
                            kontaktdata.push({name: name, usrid: data[i].usr});
                        }

                        //END!!!!!!!!

                        console.log(kontaktdata);
                    }
                });
            }
        });
    }
});

ajaxQuery.done(function(response) {alert("done");});

您可以使用延迟承诺 (http://api.jquery.com/deferred.promise):

像这样的东西应该可以工作(我没有测试过!):

var ajaxQuery = function () {
    var dfd = new jQuery.Deferred();

    $.ormon('ajax', {
            [...]

            $.ormon('ajax', {
                    [...]

                    $.ormon('ajax', {
                            [...]

                            success: function(data) {
                                    dfd.resolve(data);
                            }
                    });
            });
    });

    return dfd;
};

ajaxQuery().done(function (data) { [...] });

您可以在嵌套调用中调用 done() 方法:

var ajaxQuery = $.ormon('ajax', {
    url: '../getjson',
    trtyp: 'adm1034',
    dataType: 'json',
    data: {
        clients: 1
    },
    success: function (data) {
        console.log("1");
        for (i = 0; i < data.length; i++) {
            var name = data[i].adr1 + " " + data[i].adr2;
            kontaktdata.push({
                name: name,
                usrid: data[i].usr
            });
        }

        $.ormon('ajax', {
            url: '../getjson',
            trtyp: 'adm1034',
            dataType: 'json',
            data: {
                clients: 2
            },
            success: function (data) {
                console.log("2");
                for (i = 0; i < data.length; i++) {
                    var name = "(CRM Lead) - " + data[i].adr1 + " " + data[i].adr2;
                    kontaktdata.push({
                        name: name,
                        usrid: data[i].usr
                    });
                }

                $.ormon('ajax', {
                    url: '../getjson',
                    trtyp: 'adm1034',
                    dataType: 'json',
                    data: {
                        clients: 3
                    },
                    success: function (data) {
                        console.log("3");
                        for (i = 0; i < data.length; i++) {
                            var name = "(MXVV Kunden) - " + data[i].adr1 + " " + data[i].adr2;
                            kontaktdata.push({
                                name: name,
                                usrid: data[i].usr
                            });
                        }

                        //END!!!!!!!!

                        console.log(kontaktdata);
                    }
                }).done(function (response) {
                    alert("done");
                });
            }
        });
    }
});

而不是使用 donesuccess 回调,您应该使用 then,它 链接 异步操作并为您提供承诺最后的结果。在您的情况下,它看起来像这样:

var kontaktdata = [];
var ajaxQuery = $.ormon('ajax', {
    url: '../getjson',
    trtyp: 'adm1034',
    dataType: 'json',
    data: {clients: 1}
}).then(function(data) {
    console.log("1");
    for (var i = 0; i < data.length; i++) {
        var name = data[i].adr1 + " " + data[i].adr2;
        kontaktdata.push({name: name, usrid: data[i].usr});
    }
    return $.ormon('ajax', {
//  ^^^^^^ return another promise from the callback
        url: '../getjson',
        trtyp: 'adm1034',
        dataType: 'json',
        data: {clients: 2}
    });
}).then(function(data) {
    console.log("2");
    for (var i = 0; i < data.length; i++) {
        var name = "(CRM Lead) - " + data[i].adr1 + " " + data[i].adr2;
        kontaktdata.push({name: name, usrid: data[i].usr});
    }
    return $.ormon('ajax', {
        url: '../getjson',
        trtyp: 'adm1034',
        dataType: 'json',
        data: {clients: 3}
    });
}).then(function(data) {
    console.log("3");
    for(var i = 0; i < data.length; i++) {
        var name = "(MXVV Kunden) - " + data[i].adr1 + " " + data[i].adr2;
        kontaktdata.push({name: name, usrid: data[i].usr});
    }
    return kontaktdata; //END!!!!!!!!
});

ajaxQuery.done(function(result) {
    console.log(result);
    alert("done");
});

好的,这很好用,但看起来仍然很乏味。如果要发出的请求不止 3 个怎么办?你想在循环中对此进行编码,现在很容易实现:

var ajaxQuery = $.when([]);
for (var client=1; client<=3; client++) (function(client) {
    ajaxQuery = ajaxQuery.then(function(kontaktdata) {
        return  $.ormon('ajax', {
            url: '../getjson',
            trtyp: 'adm1034',
            dataType: 'json',
            data: {clients: client}
        }).then(function(data) {
            console.log(client);
            for (var i = 0; i < data.length; i++) {
                kontaktdata.push({
                    name: data[i].adr1 + " " + data[i].adr2,
                    usrid: data[i].usr
                });
            return kontaktdata;
        });
    });
}(client)); // necessary extra scope for closure

ajaxQuery.done(function(result) {
    console.log(result);
    alert("done");
});

有了 promises,它会变得更好 - 您可以轻松地并行发送所有三个请求,然后 wait until they're all done,并连接结果:

var requests = [];
for (var client=1; client<=3; client++)
    requests.push($.ormon('ajax', {
        url: '../getjson',
        trtyp: 'adm1034',
        dataType: 'json',
        data: {clients: client}
    }).then(function(data) {
        return data.map(function(d) {
            return {name: d.adr1+" "+d.adr2, usrid: d.usr};
        });
    }));
var ajaxQuery = $.when.apply($, requests).then(function() {
    return [].concat.apply([], arguments);
});
ajaxQuery.then(function(result) {
    console.log(result);
    alert("done");
}, function(err) {
    console.error(err + " went wrong");
});

使用 promises 的额外好处是任何 ajax 失败或异步异常都将被捕获,您可以在最后放置一个 catch 类处理程序。