466 votes

Un tableau de Deferreds $.lorsque()

Voici un exemple artificiel de ce qu'il se passe: http://jsfiddle.net/adamjford/YNGcm/20/

HTML:

<a href="#">Click me!</a>
<div></div>

JavaScript:

function getSomeDeferredStuff() {
    var deferreds = [];

    var i = 1;
    for (i = 1; i <= 10; i++) {
        var count = i;

        deferreds.push(
        $.post('/echo/html/', {
            html: "<p>Task #" + count + " complete.",
            delay: count
        }).success(function(data) {
            $("div").append(data);
        }));
    }

    return deferreds;
}

$(function() {
    $("a").click(function() {
        var deferreds = getSomeDeferredStuff();

        $.when(deferreds).done(function() {
            $("div").append("<p>All done!</p>");
        });
    });
});

Je veux "Tout fait!" apparaît après tout de report de tâches terminées, mais $.when() ne semble pas savoir comment gérer un tableau de report d'objets. "Tout fait!", se passe d'abord, parce que le tableau n'est pas un Différé d'objet, de sorte que jQuery va de l'avant et suppose que c'est juste de faire.

Je sais que l'on pourrait passer les objets dans la fonction comme $.when(deferred1, deferred2, ..., deferredX) , mais on ne sait pas combien Différés objets y seront à l'exécution dans le réel problème, je vais essayer de résoudre.

763voto

Alnitak Points 143355

Pour passer un tableau de valeurs pour toute fonction que normalement attend d'eux d'être des paramètres, utilisez Function.apply, dans ce cas, vous avez besoin de:

$.when.apply($, my_array);

Voir http://jsfiddle.net/YNGcm/21/

112voto

crispyduck Points 496

Les solutions de contournement ci-dessus (merci!) ne pas traiter correctement le problème de récupérer les objets fournis pour le report de l' resolve() méthode parce que jQuery appelle l' done() et fail() des rappels avec des paramètres individuels, pas un tableau. Cela signifie que nous devons utiliser l' arguments pseudo-tableau pour obtenir tous les résolu/a rejeté les objets retournés par la matrice de deferreds, ce qui est laid:

$.when.apply($,deferreds).then(function() {
     var objects=arguments; // The array of resolved objects as a pseudo-array
     ...
};

Depuis que nous avons passé dans un tableau de deferreds, il serait bon de revenir un tableau de résultats. Il serait bon de revenir un tableau réel au lieu d'un pseudo-tableau nous pouvons donc utiliser des méthodes comme Array.sort().

Voici une solution inspirée par when.js' when.all() méthode qui répond à ces problèmes:

// Put somewhere in your scripting environment
if (jQuery.when.all===undefined) {
    jQuery.when.all = function(deferreds) {
        var deferred = new jQuery.Deferred();
        $.when.apply(jQuery, deferreds).then(
            function() {
                deferred.resolve(Array.prototype.slice.call(arguments));
            },
            function() {
                deferred.fail(Array.prototype.slice.call(arguments));
            });

        return deferred;
    }
}

Maintenant, vous pouvez tout simplement passer un tableau de deferreds/promesses et obtenir un tableau de résolu/a rejeté les objets de votre rappel, comme suit:

$.when.all(deferreds).then(function(objects) {
    console.log("Resolved objects:", objects);
});

38voto

Eli Points 7034

Vous pouvez appliquer l' when méthode de la matrice:

var arr = [ /* Deferred objects */ ];

$.when.apply($, arr);

Comment travaillez-vous avec un tableau de jQuery Deferreds?

-1voto

mastaBlasta Points 343

Si vous êtes en utilisant angularJS ou une variante de la Q promesse de la bibliothèque, alors vous avez un .all() méthode qui permet de résoudre ce problème exact.

var savePromises = [];
angular.forEach(models, function(model){
  savePromises.push(
    model.saveToServer()
  )
});

$q.all(savePromises).then(
  function success(results){...},
  function failed(results){...}
);

voir l'intégralité de l'API:

https://github.com/kriskowal/q/wiki/API-Reference#promiseall

https://docs.angularjs.org/api/ng/service/$q

-2voto

ForceUser Points 51

Aussi, vous pouvez remplacer $.when méthode de travail avec des tableaux aux côtés de paramètres habituels

(function(when){
    $.when = function() {
        var deferredList=[];
        for(var i=0;i<arguments.length;i++){
            deferredList=deferredList.concat(arguments[i]);
        }
        return when.apply($, deferredList);
    }
})($.when);

si vous pouvez faire quelque chose comme

$.when(def1,[def2,def3,def4],def5); 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X