jQuery Deferred - waiting for multiple AJAX reques

2019-01-01 03:31发布

This question already has an answer here:

I have a three layer deep chain of deferred ajax calls, and ideally they are going to kick the promise all the way up when the deepest layer finishes (makes me thing of Inception... "we need to go deeper!").

The problem is that I'm sending off many ajax requests (possibly hundreds) at once and need to defer until all of them are done. I can't rely on the last one being done last.

function updateAllNotes() {
    return $.Deferred(function(dfd_uan) {
        getcount = 0;
        getreturn = 0;
        for (i = 0; i <= index.data.length - 1; i++) {
            getcount++;
            $.when(getNote(index.data[i].key)).done(function() {
                // getNote is another deferred
                getreturn++
            });
        };
        // need help here
        // when getreturn == getcount, dfd_uan.resolve()
    }).promise();
};

3条回答
弹指情弦暗扣
2楼-- · 2019-01-01 04:13

If you refer to jQuery.When doc, if one of your ajax call fails, fail master callback will be called even if all following ajax call haven't finished yet. In this case you are not sure that all your calls are finished.

If you want to wait for all your calls, no matter what the result is, you must use another Deferred like this :

$.when.apply($, $.map(data, function(i) {
    var dfd = $.Deferred();
    // you can add .done and .fail if you want to keep track of each results individualy
    getNote(i.key).always(function() { dfd.resolve(); });
    return dfd.promise();
});
查看更多
宁负流年不负卿
3楼-- · 2019-01-01 04:14

Thanks for the answer brittohalloran. I'm also using Underscore, so I was able to apply your solution very cleanly with map, kinda like this:

$.when.apply($, _.map(data, function(i) {
    return getNote(i.key);
})).done(function() {
    alert('Be Happy');
});

Wicked useful.

查看更多
像晚风撩人
4楼-- · 2019-01-01 04:18

You can use .when(), and .apply() with multiple deferred. Extremely useful:

function updateAllNotes() {
    var getarray = [],
        i, len;

    for (i = 0, len = data.length; i < len; i += 1) {
        getarray.push(getNote(data[i].key));
    };

    $.when.apply($, getarray).done(function() {
        // do things that need to wait until ALL gets are done
    });
}
查看更多
登录 后发表回答