Domanda

Ho un'applicazione che richiede che i dati vengano caricati in un determinato ordine: l'URL root, quindi gli schemi, quindi infine inizializza l'applicazione con gli schemi e gli URL per i vari oggetti dati. Man mano che l'utente naviga nell'applicazione, gli oggetti dati vengono caricati, validati rispetto allo schema e visualizzati. Man mano che l'utente gregge i dati, gli schemi forniscono la convalida del primo passaggio.

Ho un problema con l'inizializzazione. Uso una chiamata AJAX per recuperare l'oggetto root, $ .When (), quindi creare una serie di promesse, una per ogni oggetto schema. Che funzioni. Vedo il recupero nella console.

Quindi vedo il recupero per tutti gli schemi, quindi ogni $ .ajax () si chiama. fetchschemas () restituisce effettivamente una serie di promesse.

Tuttavia, quella clausola finale quando () non si accende mai e la parola "fatta" non appare mai sulla console. Il codice sorgente su jQuery-1.5 sembra implicare che "null" sia accettabile come oggetto per passare a $ .When.apply (), come quando () costruirà un oggetto Defered () interno per gestire l'elenco se nessun oggetto è Passato.

Questo ha funzionato usando Futures.js. Come dovrebbe essere gestita una serie di jQuery differiti, se non così?

    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);
        });
    });
È stato utile?

Soluzione

Stai cercando

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

Funzionerà anche (per un certo valore di lavoro, non risolverà l'Ajax rotto):

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

Ti consigliamo di passare $ invece di null affinché this dentro $.when si riferisce a jQuery. Non dovrebbe importare per la fonte, ma è meglio di passare null.

Deriditi tutti i tuoi $ .ajax sostituendoli $.when e il campione lavori

Quindi è un problema nella tua richiesta Ajax o nell'array la tua scomparsa a fetch_schemas.

Altri suggerimenti

La soluzione alternativa sopra (grazie!) Non affronta correttamente il problema di recuperare gli oggetti forniti ai differiti resolve() metodo perché jQuery chiama il done() e fail() callback con singoli parametri, non un array. Ciò significa che dobbiamo usare il arguments pseudo-array per ottenere tutti gli oggetti risolti/rifiutati restituiti dalla matrice di differiti, che è brutto:

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

Da quando siamo passati in una serie di differiti, sarebbe bello recuperare una serie di risultati. Sarebbe anche bello recuperare un vero array anziché uno pseudo-array in modo da poter usare metodi come Array.sort().

Ecco una soluzione ispirata da quando.js'S when.all() Metodo che affronta questi problemi:

// 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;
    }
}

Ora puoi semplicemente passare in una serie di differiti/promesse e riprendere una serie di oggetti risolti/rifiutati nel callback, in questo modo:

$.when.all(promises).then(function(schemas) {
     console.log("DONE", this, schemas); // 'schemas' is now an array
}, function(e) {
     console.log("My ajax failed");
});

Se si utilizza la versione ES6 di JavaScript, esiste un operatore di diffusione (...) che converte l'array di oggetti in argomenti separati da virgola.

$.when(...promises).then(function() {
 var schemas=arguments; 
};

Maggiori informazioni sull'operatore di spread ES6 https://developer.mozilla.org/en-us/docs/web/javascript/reference/operator/spread_operator Trova qui

si estende quando con questo codice:

var rawWhen = $.when
$.when = function(promise) {
    if ($.isArray(promise)) {
        var dfd = new jQuery.Deferred()
        rawWhen.apply($, promise).done(function() {
            dfd.resolve(Array.prototype.slice.call(arguments))
        }).fail(function() {
            dfd.reject(Array.prototype.slice.call(arguments))
        })
        return dfd.promise()
    } else {
        return rawWhen.apply($, arguments)
    }
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top