2012-12-28 12 views
5

w javascript, mam dwa asychronous wnioski dla danych:Gwarantowanie asynchroniczne żądania oddzwonienia kolejność JavaScript

$.getJSON('http://foo.com', fooQuery, fooSuccess(data)); 
$.getJSON('http://bar.com', barQuery, barSuccess(data)); 

i dwa wywołania zwrotne do przetwarzania odebranych danych:

fooSuccess(data) { // Stuff } 
barSuccess(data) { // More Stuff } 

Jak mogę zapewnić barSuccess jest wykonywane tylko po zakończeniu fooSuccess?

Uwagi:

  • chcę zachować żądania danych, ponieważ są one: asynchroniczny i bez blokowania (od odpowiedzi serwera może chwilę potrwać).
  • Ale chcę wywołań zwrotnych, które przetwarzają dane do wykonania sekwencyjnie. Oznacza to, że nie chcę wykonywać barSuccess, dopóki nie zakończy się fooSuccess.

Dziękuję bardzo za mądrość i pomoc!

+4

Chcesz [obietnica jQuery/obiekt odroczony] (http://api.jquery.com/category/deferred-object/). –

+0

@JaredFarrish sprawiają, że jest to odpowiedź! – Colleen

+0

O tak, jest też nowsza ['jQuery.Callbacks()'] (http://api.jquery.com/category/callbacks-object/). –

Odpowiedz

5

Oto, jak można to zrobić przy użyciu obiektu odroczonego jQuery, który jest zwracany przez żądania ajax.

var fooDfd = $.getJSON('http://foo.com', fooQuery); 
var barDfd = $.getJSON('http://bar.com', barQuery); 

fooDfd.then(function(fooData){ 
    fooSuccess(fooData); 
    barDfd.then(barSuccess); 
}); 

+0

Podczas, gdy robi się to, co OP chce zrobić, może lepiej użyć konstruktu '$ .when(). Done()', aby wywoływać AJAX równolegle. –

+0

To jest idealne! Tak zwięzły i robi dokładnie to, co chcę. Wielkie dzięki David. –

+1

@MikeBrant Wywołania _jest_ wykonywane równolegle, są uruchamiane przez pierwsze 2 linie. – david

-1

Połóż wywołanie barSuccess w oddzwonieniu powitalnym .

fooSuccess(data){ 
    jQuery.ajax({ 
    data: data, 
    success: function(response){ 
     barSuccess(data) //should still be in scope, I think? 
    } 
    } 
} 
+0

To nie pozwoli 'barSuccess' na dostęp do zwracanej wartości' barQuery'. – Amadan

+0

dobry punkt. Dokona edycji. – Colleen

+0

Po aktualizacji: powoduje połączenie wywołań AJAX, czego OP nie chce. W tym celu potrzebne są obietnice lub ręczny kod. – Amadan

5

Najlepszym sposobem byłoby wykorzystać jQuery when().done() funkcjonalność takiego:

$.when(
    $.getJSON('http://foo.com', fooQuery, fooSuccess(data)), 
    $.getJSON('http://bar.com', barQuery, barSuccess(data)) 
).done(function(arg1, arg2){ 
    fooSuccess(arg1); 
    barSuccess(arg2); 
}); 

To pozwoli na jednoczesne wykonanie żądań AJAX i gwarantuje wykonanie funkcji done() raz wszystko żądania zostały pomyślnie zakończone.

+0

Wielkie dzięki Mike! Nie wiedziałem, że było tak wiele różnych sposobów na zrobienie tego z jQuery. Gdybym nie był takim nowicjuszem, przegłosowałbym zarówno twoją odpowiedź, jak i Davida (wciąż poniżej progu punktowego do przegłosowania). –

+0

Różnica między naszymi dwiema odpowiedziami polega na tym, że pozwoliłem, aby program obsługi 'fooSuccess' działał tylko z odpowiedzią z' http: // foo.com', zamiast czekać na zakończenie paska. – david

+0

@david Indeed. Myślę, że właściwym podejściem byłoby zobaczyć, która metoda zapewnia najlepszy ogólny czas reakcji. Sądzę, że zakładałem, że wywołania ajaxowe będą najbardziej czasochłonne i że programy do obsługi sukcesów będą mniej czasochłonne, co oznacza, że ​​najlepiej będzie wykonywać połączenia równolegle. Jeśli konieczne jest uruchomienie 'fooSuccess' w najwcześniejszym możliwym punkcie, twoje podejście byłoby lepsze we wszystkich przypadkach, w których wywołanie AJAX' foo' zajmuje mniej czasu niż wywołanie AJAX 'bar'. Podsumowując, PO powinien być może przetestować oba sposoby i zobaczyć, co ma dla nich sens. –

1

Podążam za tym bardzo interesującym wpisem od pół godziny temu, kiedy pojawiło się eleganckie rozwiązanie zaprezentowane przez @Mike Brant, szybko znalazłem się w bibliotece jquery, aby zobaczyć, jak powstaje magia. Czy nie? Polecam, jest bardzo interesujący! BTW Myślę, że nie potrzebujemy całej tej magii, nie w tym przypadku mamy dwie asynchroniczne funkcje obsługi wywołań (funkcje), bez względu na to, który koniec najpierw musimy wiedzieć, kiedy drugi koniec, to wszystko czego potrzebujemy to trzecia funkcja, która zostanie wywołana przez dwie procedury obsługi i działać, gdy wszystkie dane będą gotowe. Wiem, że to podejście zmarnuje cztery lub pięć linii więcej kodu niż eleganckie rozwiązanie jquery, ale na końcu nasz mózg i dusza będą w lepszym stanie. Przepraszam za mój angielski.

Powiązane problemy