2012-09-05 18 views
16

Mam sytuację, w której moje wywołania ajax muszą działać w określonej kolejności. Używałem obiektów odroczonych jQuery w innych sytuacjach, ale nie mogę znaleźć sposobu, aby to odpowiednio się zachowywało.jQuery odroczony obiekt z zagnieżdżonymi wywołaniami ajax

Mam funkcję, która wykonuje wiele żądań ajax w swoim życiu. Niektóre żądania będą wykonywane podczas oddzwaniania powodzenia innych żądań.

Moje pytanie: Czy istnieje sposób, aby zwrócić wszystkie zagnieżdżone odroczone obiekty do oryginalnego połączenia $.when?

Uproszczony Przykładem może być:

function nestedAjax() { 
    $.get("/", function(){ 
     console.log("First ajax done."); 
     $.get("/", function(){ 
      console.log("Second ajax done."); 
     }); 
    }); 
}; 

staram się mieć funkcję nestedAjax do korzystania $.when() i $.done() tak:

$.when(nestedAjax()).done(function(){ 
    console.log("Complete"); 
});​ 

z odczytem wyjścia konsoli:

> First ajax done. 
> Second ajax done. 
> Complete. 

I może wrócić pierwszy get do osiągnięcia tego celu:

> First ajax done. 
> Complete. 
> Second ajax done. 

Ale oczywiście nie jest to, czego potrzebują. Każda pomoc będzie doceniona.

+0

jeśli muszą występować w kolejności, dlaczego nie wykonywać synchronicznych żądań w pierwszej kolejności? Przestań próbować dopasować kwadratowy kołek w okrągłym otworze. –

+0

Masz rację. Dzięki za wywołanie budzika. Udało mi się zmienić i osiągnąć pożądaną funkcjonalność. Wciąż jednak jestem zainteresowany, jeśli istnieje sposób na "zbieranie" odroczonych obiektów z zagnieżdżonych wywołań ajaxowych do oceny, więc moje pytanie wciąż jest aktualne. – Aesthete

+0

To jest w porządku. :) Mogę nie być tutaj poza bazą - jest bardzo późno i pracowałem - ale może w funkcji wywołania zwrotnego każdego wywołania AJAX mógłbyś dodać obiekt do tablicy? Możesz przekazać tablicę przez łańcuch jako argument lub pozostawić go w przestrzeni globalnej. –

Odpowiedz

14

To całkiem proste. Chociaż wszystkie wywołania AJAX są obiektami odroczonymi, nadal używam jednego dla samej metody.

+0

Dzięki, używam ich częściej i teraz widzę, dlaczego nie mogę zrobić dokładnie tego, co próbowałem zrobić. Dzięki za pomoc. – Aesthete

+0

oczywiście !! Waliłem głową o odroczone przez kilka godzin, po prostu nie nawiązałem połączenia. dzięki Dr !! – Doga

+0

-1 dla niepoprawnych błędów. Sprawdź odpowiedź @ dmnd. – Bergi

1

Nie można dodać komentarza z jakiejś przyczyny do powyższej odpowiedzi.

Dodam tutaj mój komentarz. Powyższa odpowiedź zadziała tylko wtedy, gdy wywołania ajax są szybkie i zwrócą PRZED zwrotem dfd.promise().

Mam ten sam problem. I jak widać. Zwrócony odroczony obiekt stwierdza, że ​​jest "oczekujący": http://jsfiddle.net/BtEKa/

+0

Tak, masz absolutną rację. Jest to coś, co doszedłem do wniosku, i w mojej sytuacji mam wiele żądań AJAX działających w tej samej funkcji. Najbliższym rozwiązaniem moich problemów było użycie '$ .ajaxComplete()', ale przeprojektowałem swoje podejście i sprawiłem, że działał on czysto. – Aesthete

+0

Ale pamiętaj, że jeśli to zrobisz. Zdarzenie zostanie uruchomione w końcu po rozwiązaniu/odrzuceniu obiektu. To był mój problem. Mój obiekt zwrócił stan "oczekujący"() ... kilka sekund później to się zmieniło i moje zdarzenia zaczęły się odpalać. – Juw

+0

W pythonie istnieje możliwość "uzyskania" wyniku ze struktury kontrolnej. To wydaje się być tym, czego bym potrzebował, gdzie wiele wywołań ajaxowych mogłoby dać wynik i po otrzymaniu wszystkich wyników mógł zostać rozwiązany "master" odroczony obiekt. Jest oczywiste, że walka z językiem, aby uzyskać pewne zachowanie z tego powodu, jest zwykle oznaką konieczności zmiany podejścia. – Aesthete

6

Nie potrzebujesz w rzeczywistości dodatkowego obiektu odroczonego. Możesz robić co chcesz przez łańcuchowym z then():

function nestedAjax() { 
    return $.get("/echo/json/").then(function(result1){ 
     console.log("First ajax done."); 
     if (result1) { 
      return result1; 
     } else { 
      return $.get("/echo/json/").then(function(nestedResult){ 
       console.log("Second ajax done."); 
       return nestedResult; 
      }); 
     } 
    }); 
}; 

dodałam trochę logiki, ponieważ myślę, że to prawdopodobnie powód, dla którego realizujemy to synchronicznie. Po tym można użyć wynik w $.when tak:

$.when(nestedAjax(), $.get("/something/else")).then(function(nested, other) { 
    console.log("Complete.", nested, other); 
}); 
+0

Nie dostaję tu/else. Czy to powstrzymałoby wydanie drugiego zaproszenia? Proszę wyjaśnić. – Cymbals

+1

Tak, drugie wywołanie Ajax zostanie wydane tylko wtedy, gdy wynikiem pierwszego jest prawda. – dmnd

+1

@dmnd: Myślę, że miałeś na myśli "jeśli wynikiem pierwszego jest falsy". –

Powiązane problemy