132 votes

Comment travaillez-vous avec un tableau de jQuery Deferreds ?

J'ai une application qui nécessite des données chargées dans un certain ordre: l'URL de la racine, puis les schémas, puis enfin initialiser l'application avec les schémas et les url pour les différents objets de données. En tant que l'utilisateur quitte l'application, les objets de données sont chargés, validé par rapport au schéma, et affiché. En tant qu'utilisateur CRUDs les données, les schémas de fournir de la première étape de la validation.

Je vais avoir un problème avec l'initialisation. J'utilise un appel Ajax pour récupérer l'objet racine, $.lors de la(), puis créer un tableau de promesses, un pour chaque schéma de l'objet. Qui fonctionne. Je vois le chercher dans la console.

Je vois alors l'extraction de tous les schémas, de sorte que chaque $.ajax() fonctionne. fetchschemas (), en effet, de retourner un tableau de promesses.

Cependant, ce dernier lorsque() de la clause jamais les incendies et le mot "FAIT" n'apparaît pas sur la console. Le code source de jquery 1.5 semble impliquer que "null" est acceptable comme un objet pour passer de $.lors de l'.appliquer(), comme lors de l'() va créer un interne en Différé() de l'objet de gérer la liste si aucun objet n'est passé.

Cette travaillé à l'aide de Futures.js. Comment devrait-un tableau de jQuery Deferreds être géré, si ce n'est comme cela?

    var fetch_schemas, fetch_root;

    fetch_schemas = function(schema_urls) {
        var fetch_one = function(url) {
            return $.ajax({
                url: url,
                data: {},
                contentType: "application/json; charset=utf-8",
                dataType: "json"
            });
        };

        return $.map(schema_urls, fetch_one);
    };

    fetch_root = function() {
        return $.ajax({
            url: BASE_URL,
            data: {},
            contentType: "application/json; charset=utf-8",
            dataType: "json"
        });
    };

    $.when(fetch_root()).then(function(data) {
        var promises = fetch_schemas(data.schema_urls);
        $.when.apply(null, promises).then(function(schemas) {
            console.log("DONE", this, schemas);
        });
    });

198voto

Raynos Points 82706

Vous êtes à la recherche pour

$.when.apply($, promises).then(function(schemas) {
     console.log("DONE", this, schemas);
}, function(e) {
     console.log("My ajax failed");
});

Cela permettra également de travailler (pour une certaine valeur de travail, il ne sera pas corrigé cassé ajax):

$.when.apply($, promises).done(function() { ... }).fail(function() { ... });` 

Vous aurez envie de passer $ au lieu de null afin this à l'intérieur d' $.when désigne jQuery. Il ne devrait pas question pour la source, mais c'est mieux que de passer null.

Moqué de tous vos $.ajax pour les remplacer par $.when et les exemples d' œuvres

Donc c'est soit un problème dans ta requête ajax ou le tableau de votre passage à fetch_schemas.

53voto

crispyduck Points 496

La solution 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($, promises).then(function() {
     var schemas=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(promises).then(function(schemas) {
     console.log("DONE", this, schemas); // 'schemas' is now an array
}, function(e) {
     console.log("My ajax failed");
});

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