Jak pracować z tablicą jQuery?

Mam aplikację, która wymaga, aby dane były ładowane w określonej kolejności: główny adres URL, następnie Schematy, a następnie w końcu zainicjować aplikację ze schematami i adresami URL dla różnych obiektów danych. Gdy użytkownik porusza się po aplikacji, Obiekty danych są ładowane, sprawdzane na podstawie schematu i wyświetlane. Gdy użytkownik przeczyta dane, Schematy zapewniają walidację pierwszego przejścia.

Mam problem z inicjalizacją. Używam wywołania Ajax do pobrania obiektu root,$.kiedy(), następnie utwórz tablicę obietnic, po jednej dla każdego obiektu schematu. To działa. Widzę aport w konsoli.

Następnie widzę fetch dla wszystkich schematów, więc każdy $.funkcja ajax () działa. fetchschemas () rzeczywiście zwraca tablicę obietnic.

Jednak ta końcowa klauzula when () nigdy nie zostanie wywołana, a słowo "zrobione" nigdy nie pojawi się na konsoli. Kod źródłowy jquery - 1.5 wydaje się sugerować, że "null" jest akceptowalny jako obiekt do przekazania do $.kiedy.apply (), ponieważ kiedy () zbuduje wewnętrzny obiekt Deferred() do zarządzania listą, jeśli nie zostanie przekazany żaden obiekt.

To działało przy użyciu Futures.js. Jak należy zarządzać tablicą jQuery Deferreds, jeśli nie w ten sposób?

    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);
        });
    });
Author: Bergi, 2011-02-02

4 answers

Szukasz

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

To również zadziała (dla jakiejś wartości pracy, nie naprawi złamanego Ajaxu):

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

Będziesz chciał przekazać $ zamiast null, Aby this wewnątrz $.when odnosiło się do jQuery. Nie powinno to mieć znaczenia dla źródła, ale lepiej jest przekazać null.

/ Align = "left" / ajax poprzez zastąpienie ich przez $.when i próbka Działa

Więc jest to albo problem w żądaniu ajax lub tablicy, do której przekazujesz fetch_schemas.

 192
Author: Raynos,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-02-22 19:58:48

Obejście powyżej (dzięki!) nie rozwiązuje problemu z powrotem obiektów dostarczonych do metody resolve() deferred, ponieważ jQuery wywołuje wywołania zwrotne done() i fail() z indywidualnymi parametrami, a nie tablicą. Oznacza to, że musimy użyć pseudo-tablicy arguments, aby uzyskać wszystkie rozwiązane / odrzucone obiekty zwrócone przez tablicę deferredów, co jest brzydkie:

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

Ponieważ przeszliśmy w tablicy odroczeń, byłoby miło odzyskać tablicę wyników. Byłoby byłoby też miło odzyskać rzeczywistą tablicę zamiast pseudo-tablicy, abyśmy mogli używać metod takich jak Array.sort().

Oto rozwiązanie inspirowane kiedy.metoda js'S when.all(), która rozwiązuje te problemy:

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

Teraz możesz po prostu przekazać tablicę deferreds / promises i odzyskać tablicę rozwiązanych / odrzuconych obiektów w Twoim wywołaniu zwrotnym, tak:

$.when.all(promises).then(function(schemas) {
     console.log("DONE", this, schemas); // 'schemas' is now an array
}, function(e) {
     console.log("My ajax failed");
});
 51
Author: crispyduck,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-04-25 06:59:25

Jeśli używasz wersji ES6 javascript, istnieje operator spread(...), który konwertuje tablicę obiektów na argumenty rozdzielone przecinkami.

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

Więcej o operatorze spreadu ES6 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_operator Znajdź tutaj

 18
Author: pashaplus,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-03-28 08:16:49

Rozszerza gdy z tym kodem:

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)
    }
}
 0
Author: CALL ME TZ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-06-16 07:10:14