[JS] Ajax synchroniczny.

0

Witam

W aplikacji przewiduje dużo paginowanych wyników.
Chciałem szczegóły z paginacją wyciągnąć do osobnego obiektu, żeby tak tego ciągle nie powtarzać.

sama funkcja pobierające dane:

Pagination.prototype.request = function(pageId) {
        query =  (pageId == undefined) ? '' : 'page='+id,
        result = undefined,
        that = this;
            $.getJSON(that.settings.url, query, function(data, status) {
                var pagination = data['pagination'];
                delete data['pagination'];
                that.createLinks(pagination);
                result = data;
            });
        return result;
};

No i lipa, JS mi nie poczeka na rezultat wykonania, i undefined pozostaje.
Dowiedziałem się, że przez ustawienia Ajax-a na tryb sync może pomoć, ale też jest to bardzo nie polecane rozwiązanie. Istnieje w ogóle jakiś inny sposób?

0

Zakładam, że używasz funkcji getJSON dostępnej w jQuery.

Jest ona w pełni asynchroniczna. Nawet ostrzega o tym dokumentacja:

"Keep in mind, that lines after this function will be executed before the callback." (źródło).

To norma dla żądań ajaxowych. Gdy AJAX było jeszcze akronimem (bo teraz niby już nie jest), pierwsze "A" oznaczało właśnie "asynchroniczny". Możesz przestawić obiekt XMLHttpRequest na tryb synchroniczny, jednak jest to wysoce niezalecane. Nie mam pojęcia, czy ta funkcja z jQuery to obsługuje -- nigdy nie potrzebowałem tego używać i nie mam zamiaru. Bo przestawienie ajaxu na tryb synchroniczny powoduje, że po wysłaniu żądania przeglądarka zamarza. Strona jest zablokowana aż do przyjścia odpowiedzi. To jest zdecydowanie be!

Obawiam się więc, że nie zrobisz tego synchronicznie i funkcja request będzie musiała być asynchroniczna. Możesz jej dać drugi parametr. Nazwij go sobie callback i przekaż do getJSON jako trzeci parametr. Funkcja callback zostanie wykonana po przyjściu odpowiedzi.

Zamiast:

zrob_cos_przed();
pagination.request(id);
zrob_pierwsza_rzecz_po();
zrob_druga_rzecz_po();

Użyjesz po prostu anonimowej funkcji i w razie potrzeby wykorzystasz domknięcie:

zrob_cos_przed();
pagination.request(id, function() {
  zrob_pierwsza_rzecz_po();
  zrob_druga_rzecz_po();
});

Możesz zawsze użyć Ajaxa ręcznie, korzystając z XHR. Możesz całkiem ominąć jQuery (tak, da się pisać kod w JS nie używając jQuery! :P), ale skoro już go używasz, to równie dobrze możesz użyć jQuery.ajax. W obiekcie z ustawieniami możesz ustawić ;) async: false i będziesz miał synchroniczne żądanie. W większości wypadków jednak zdecydowanie tego nie polecam ze względu na wspomniane wcześniej blokowanie przeglądarki.

0

@bswierczynski

Dzięki za dokładne wyjaśnienie, spróbuje Twojej propozycji.
Też mi nie pasuje ta funkcja getJSON(), ale cóż.

(tak, da się pisać kod w JS nie używając jQuery! :P)

Uwierz mi, zamierzam zacząć się uczyć JS na poważnie (nawet mnie wkręcił ten język, ogólnie to moim celem jest GWT, a JS też wypada znać) jak tylko zrobię to co mam zrobić a czas biegnie nie miłosiernie. Więc doskonale zdaje sobie sprawę, że zacząłem przygodę z JS, od tzw. 'd**y strony'.

Poza tym jak to jest jQuery chyba nie stosują w jakiś większych portalach?
Różnice w wydajności między czystym JS, a biblioteką są duże?
A może już teraz mało kto klepie w czystym JS?

0
GhostDog napisał(a)

Też mi nie pasuje ta funkcja getJSON(), ale cóż.

Ja nie powiedziałem, że mi nie pasuje ;). Jestem totalnie przyzwyczajony do pisania asynchronicznego kodu. Już nawet przestało mnie to aż tak wkurzać. Ostatnio ciąglę muszę tego ustrojstwa używać, bo jak nie operuję na plikach (asynchronicznych żądaniach), to wykonuję obliczenia trwające nawet kilka sekund. Więc potrzebuję choćby pokazać użytkownikowi ruchomy pasek postępu. Niestety, nawet jeśli umieszczę w synchronicznym bloku kodu odświeżanie paska postępu, to i tak przeglądarka go nie narysuje dopóki kod JS się wykonuje. Więc nawet długie obliczenia muszę dzielić na mniejsze kawałki i wykonywać je asynchronicznie, z powstawianym tu i ówdzie setTimeout żeby dać przeglądarce czas na odrysowanie się.

Ot, uroki JavaScriptu w przeglądarkach. Radzę się przyzwyczaić.

Na szczęście funkcyjność JavaScriptu, jakkolwiek spartańska, to jednak jest na tyle skuteczna i potężna, że pozwala na radzenie sobie z takimi kwiatkami.

GhostDog napisał(a)

Poza tym jak to jest jQuery chyba nie stosują w jakiś większych portalach?

Ależ stosują! Wykop używa. Digg. Twitter. Mozilla.

GhostDog napisał(a)

Różnice w wydajności między czystym JS, a biblioteką są duże?

To zależy. Jeśli miałbyś takiego skilla jak autorzy jQuery, to Twoje skrypty byłyby szybsze niż jQuery. Jak się zabierzesz zapisanie np. funkcji zwracającej elementy DOM na podstawie przekazanego selektora CSS, to będzie on wolniejszy niż odpowiednia funkcja jQuery. Z drugiej strony, jeśli zastosujesz natywną dla przeglądarki funkcję querySelectorAll, to będzie ona znacznie szybsza.

jQuery to ogólna biblioteka napisana w JavaScripcie, więc będzie wolniejsza niż zoptymalizowany, specjalistyczny kod w JS.

Ale jQuery jest bardzo szybką biblioteką. Będzie szczególnie szybka gdy zastosujesz się do paru zasad (np. cache'owanie obiektów jQuery, zaczynanie -- gdzie to możliwe -- selektora od #id i tak dalej).

GhostDog napisał(a)

A może już teraz mało kto klepie w czystym JS?

To znowu zależy. jQuery odniosło olbrzymi sukces. Zresztą, to bardzo dobra biblioteka. Umożliwiła "pisanie" skryptów o skomplikowanej funkcjonalności tym kolesiom, którzy bez tego za Chiny ludowe by sobie nie poradzili. Więc "ludzi piszących w jQuery" jest mnóstwo. Spotkałem się z kwiatkami takimi jak myślenie, że znak $ jest jakąś skomplikowaną częścią samego JavaScriptu (!).

Z drugiej strony... Na N-K jQuery nie ma. Na Facebooku też nie widzę (przynajmniej bez zalogowania). Na WP i Onecie też nie. A to są strony z bardzo bogatymi, skomplikowanymi skryptami.

To, że ktoś zaczyna przygodę z językiem od konkretnej biblioteki świadczy o tym, że jest fajna i dobra. Może powiedzenie, że jQuery jest dla JS tym, czym RoR dla Ruby'ego to spora przesada, ale na mniejszą skalę związek jest podobny. Tyle że nie da się pisać profesjonalnego kodu nie znając dobrze samego języka.

A do jego nauki polecam każdemu książkę "JavaScript - Mocne strony" Douglasa Crockforda. Zwięzła. Dobrze napisana. Świetnie uczy potęgi samego języka JavaScript, bez jakichś bibliotek (jak jQuery), czy nawet modułów spoza samego rdzenia języka (DOM jest takim modułem, wszak JS nie musi nawet pracować z przeglądarką).

0

Dzięki za te informacje. Pozdrawiam

1 użytkowników online, w tym zalogowanych: 0, gości: 1