使用多个Deferred和Promises - jquery

时间:2017-04-11 09:29:34

标签: javascript jquery ajax

我有一个使用jQuery 1.11.1的页面,并且已经使用了Deferred和Promises。

该页面执行大约13个单独的ajax调用,然后将一系列单选按钮填充到表中。因为ajax调用不一定按表中定义的顺序完成,所以我实现了以下内容。这有效:

function getSubscriptionTypes(st_id) {
        var d = $.Deferred();
        if(st_id){
            $.ajax({
                type: "POST",
                url: "addUser.php",
                data: { st_id: st_id },
                dataType: "json"
            }).done(function(p) {
                d.resolve(p);
            }).fail(d.reject);
            return d.promise();
        } 
    }

    function loadSubscriptionTypes() {
        $('.subsList').each(function() {
            var st_id = $(this).closest("tr").data('stId');
            var st_id = String(st_id);
            var sub_types = getSubscriptionTypes(st_id).done(function(c){

                $.each(c, function(k,v) {
                    $('#stid-'+st_id).append('<input type="radio" value="' + v.ut_id + '-' + st_id + '" data-st-id="' + st_id + '" name="stid[' + st_id + ']"> ' + v.type + ' &nbsp;');
                });
            });
        });
    }

    loadSubscriptionTypes();

我现在正在努力做以下事情 - 所有单选按钮都附加到我的表后,我想使用jQuery来定位它们(​​预先选择某些按钮)。我不确定如何做到这一点,但想象一下使用另一个 Deferred / Promise?

所以我尝试将代码修改为:

function loadSubscriptionTypes() {
    var deferredObject = $.Deferred();

    // Existing code above

    deferredObject.resolve(); 
    return deferredObject.promise();
}

var promise = loadSubscriptionTypes();

promise.done(function () {
    console.log("loadSubscriptionTypes() done");
});

当加载页面时,在所有ajax调用完成之前,我的控制台中会出现文本“loadSubscriptionTypes()done”。

基本上,在执行其他任务之前,我不知道如何告诉它等待loadSubscriptionTypes()中的所有工作完成。

请有人提出建议或指出我正确的方向吗?

PS - 我知道可能有更好的方法来编写我的代码,但是这已经使用我迄今为止能够找到/学习的内容,以及将正确的单选按钮加载到桌子,实际上是有效的。

1 个答案:

答案 0 :(得分:1)

首先,确保getSubscriptionTypes实际返回Promise。没有必要在其中创建自己的$.Deferred - 这样做是 promise antipattern

function getSubscriptionTypes(st_id) {
    return $.ajax({
            type: "POST",
            url: "addUser.php",
            data: { st_id: st_id },
            dataType: "json"
    });
}

然后,在你的loadSubscriptionTypes函数中,将所有返回的promises累积到一个数组中:

var promise = getSubscriptionTypes(st_id);
push(myArray, promise);
promise.done(function(c) {
    $.each(c, function(k,v) {
        ...
    });
});

在外部循环之后,使用$.when等待所有这些承诺得到解决:

$.when.apply($, myArray).then( ... );