web-dev-qa-db-fra.com

jQuery Deferred - en attente de plusieurs AJAX requêtes pour terminer

J'ai une chaîne profonde à trois couches d'appels ajax différés, et idéalement, ils tiendront la promesse tout le long lorsque la couche la plus profonde se terminera (cela me fait penser à Inception ... "nous devons aller plus loin!").

Le problème est que j'envoie de nombreuses demandes ajax (peut-être des centaines) à la fois et que je dois reporter jusqu'à ce que toutes soient terminées. Je ne peux pas compter sur le dernier fait en dernier.

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();
};
56
brittohalloran

Vous pouvez utiliser .when() et .apply() avec plusieurs différés. Extrêmement utile:

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
    });
}
106
brittohalloran

Si vous vous référez à jQuery.When doc, si l'un de vos appels ajax échoue, fail le rappel maître sera appelé même si tous les appels ajax suivants ne sont pas encore terminés. Dans ce cas, vous n'êtes pas sûr que tous vos appels soient terminés.

Si vous voulez attendre tous vos appels, quel que soit le résultat, vous devez utiliser un autre différé comme celui-ci:

$.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();
});
27
Mordhak

Merci pour la réponse brittohalloran. J'utilise également Underscore, j'ai donc pu appliquer votre solution très proprement avec map, un peu comme ceci:

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

Méchant utile.

7
Travis