Jak sprawić, by funkcja czekała, aż wszystkie żądania Ajax jQuery zostaną wykonane w innej funkcji?
Krótko mówiąc, muszę wykonać wszystkie żądania Ajax, zanim wykonam następne. Ale jak?
javascript
jquery
ajax
jamietelin
źródło
źródło
Odpowiedzi:
W tym celu jQuery definiuje teraz funkcję when .
Akceptuje dowolną liczbę Odroczonych obiektów jako argumenty i wykonuje funkcję, gdy wszystkie z nich zostaną rozpoznane.
Oznacza to, że jeśli chcesz zainicjować (na przykład) cztery żądania ajax, a następnie wykonać akcję po ich zakończeniu, możesz zrobić coś takiego:
Moim zdaniem zapewnia czystą i przejrzystą składnię i pozwala uniknąć zmiennych globalnych, takich jak ajaxStart i ajaxStop, które mogłyby mieć niepożądane skutki uboczne w miarę rozwoju twojej strony.
Jeśli nie wiesz z góry, na ile argumentów ajax musisz czekać (tzn. Chcesz użyć zmiennej liczby argumentów), możesz to nadal zrobić, ale jest to trochę trudniejsze. Zobacz Przekaż w tablicy Odroczone do $ .when () (i być może jQuery .w przypadku rozwiązywania problemów przy zmiennej liczbie argumentów ).
Jeśli potrzebujesz głębszej kontroli nad trybami błędów skryptów ajax itp., Możesz zapisać zwrócony obiekt
.when()
- jest to obiekt obietnicy jQuery obejmujący wszystkie oryginalne zapytania ajax. Możesz do niego zadzwonić.then()
lub.fail()
dodać szczegółowe procedury obsługi sukcesu / niepowodzenia.źródło
$.when
zwracaPromise
obiekt, który ma nie tylko bardziej użyteczne metody.done
. Na przykład za pomocą.then(onSuccess, onFailure)
metody można zareagować, gdy oba żądania zakończą się powodzeniem lub co najmniej jedno z nich zakończy się niepowodzeniem.fail
sprawą. W przeciwieństwie dodone
,fail
strzela natychmiast po pierwszej porażce i ignoruje pozostałe odroczenia.onFailure
można dołączyć funkcję. Jak zauważyłem w komentarzu do pytania PO: może on chcieć bardziej precyzyjnie wskazać, co rozumie przez „zrobione”. „Ryan Mohr” miał również bardzo dobrą opinię na temat tego, żefail
zachowuje się inaczej, ponieważdone
kilka dalszych lektur, które należy zrobić,Promises
to chyba html5rocks.com/en/tutorials/es6/promisesJeśli chcesz wiedzieć, kiedy wszystkie
ajax
żądania zostaną zakończone w twoim dokumencie, bez względu na to, ile ich istnieje, po prostu użyj zdarzenia $ .ajaxStop w ten sposób:Aktualizacja:
jeśli chcesz trzymać się
ES
składni, możesz użyć Promise.all dla znanychajax
metod:Interesującym punktem jest to, że działa zarówno z, jak
Promises
i$.ajax
żądaniami.Oto demonstracja jsFiddle .
Aktualizacja 2:
Jeszcze nowsza wersja wykorzystująca składnię asynchroniczną / oczekującą :
źródło
Znalazłem dobrą odpowiedź od gnarfa, której właśnie szukałem :)
jQuery ajaxQueue
Następnie możesz dodać do kolejki zapytanie ajax w następujący sposób:
źródło
Wykorzystaj
ajaxStop
wydarzenie.Załóżmy na przykład, że masz komunikat ładujący ... podczas pobierania 100 żądań ajax i chcesz ukryć tę wiadomość po załadowaniu.
Z dokumentu jQuery :
Pamiętaj, że będzie czekać na wszystkie żądania ajax wykonane na tej stronie.
źródło
UWAGA: Powyższe odpowiedzi wykorzystują funkcjonalność, która nie istniała w chwili pisania tej odpowiedzi. Zalecam stosowanie
jQuery.when()
zamiast tych metod, ale pozostawiam odpowiedź do celów historycznych.-
Prawdopodobnie możesz sobie poradzić z prostym semaforem liczącym, chociaż sposób jego implementacji będzie zależał od twojego kodu. Prostym przykładem byłoby coś takiego ...
Jeśli chcesz, aby działało to jak {async: false}, ale nie chciałeś blokować przeglądarki, możesz to samo zrobić z kolejką jQuery.
źródło
.get()
. W ten sposób przynajmniej nie powielasz tego kodu. Nie tylko to, ale deklarowanie zafunction(){}
każdym razem przydziela pamięć za każdym razem! Raczej zła praktyka, jeśli można wywołać funkcję zdefiniowaną statycznie.javascript jest oparty na zdarzeniach, więc nigdy nie powinieneś czekać , raczej ustaw haki / callbacki
Prawdopodobnie możesz po prostu użyć powodzenia / kompletnych metod jquery.ajax
Lub możesz użyć .ajaxComplete :
chociaż powinieneś opublikować pseudokod, w jaki sposób twoje (a) żądania (a) ajaxowe są (są) wywoływane, aby być bardziej precyzyjnym ...
źródło
Trochę tego obejścia:
Nadzieja może się przydać ...
źródło
jQuery pozwala określić, czy chcesz, aby żądanie ajax było asynchroniczne, czy nie. Możesz po prostu zsynchronizować żądania ajax, a wtedy reszta kodu nie zostanie wykonana, dopóki nie zostaną zwrócone.
Na przykład:
źródło
Jeśli potrzebujesz czegoś prostego; raz i gotowe oddzwonienie
źródło
Możesz także użyć async.js .
Myślę, że jest lepszy niż $ .when, ponieważ można scalić wszystkie rodzaje wywołań asynchronicznych, które nie obsługują obietnic po wyjęciu z pudełka, takich jak limity czasu, wywołania SqlLite itp., A nie tylko żądania ajax.
źródło
Na podstawie odpowiedzi @BBonifield napisałem funkcję narzędzia, dzięki której logika semaforów nie rozprzestrzenia się we wszystkich wywołaniach ajax.
untilAjax
to funkcja narzędziowa, która wywołuje funkcję zwrotną po zakończeniu wszystkich wywołań ajaxCall.ajaxObjs
jest tablicą obiektów ustawień ajax[http://api.jquery.com/jQuery.ajax/]
.fn
jest funkcją oddzwanianiaPrzykład:
doSomething
zastosowania funkcjiuntilAjax
.źródło
Zdecydowanie polecam użycie $ .when (), jeśli zaczynasz od zera.
Mimo że to pytanie ma ponad milion odpowiedzi, nadal nie znalazłem nic przydatnego w mojej sprawie. Powiedzmy, że masz do czynienia z istniejącą bazą kodów, już wykonując kilka wywołań ajax i nie chcesz wprowadzać złożoności obietnic i / lub przerobić całą sprawę.
Możemy łatwo wykorzystać jQuery
.data
,.on
a.trigger
funkcje, które były częścią jQuery od zawsze.Codepen
Dobra rzecz w moim rozwiązaniu to:
oczywiste jest, na czym dokładnie zależy oddzwonienie
funkcja
triggerNowOrOnLoaded
nie dba o to, czy dane zostały już załadowane, czy nadal na nie czekamybardzo łatwo jest podłączyć go do istniejącego kodu
źródło
Używam sprawdzania rozmiaru po zakończeniu ładowania całego ajax
źródło
Aby rozwinąć odpowiedź Alexa, mam przykład ze zmiennymi argumentami i obietnicami. Chciałem załadować obrazy za pośrednictwem ajax i wyświetlić je na stronie po ich załadowaniu.
Aby to zrobić, użyłem następującego:
Zaktualizowany do pracy z jednym lub wieloma adresami URL: https://jsfiddle.net/euypj5w9/
źródło
Jak wspomniano w innych odpowiedziach, możesz
ajaxStop()
poczekać, aż wszystkie żądania ajax zostaną zakończone.Jeśli chcesz to zrobić dla konkretnego
ajax()
żądania, najlepiej możesz użyćcomplete()
metody wewnątrz określonego żądania ajax:Ale jeśli musisz poczekać tylko na kilka i pewne żądania ajax, które mają zostać wykonane? Skorzystaj ze wspaniałych obietnic javascript, aby poczekać, aż te aukcje, na które chcesz czekać, zostaną zakończone. Zrobiłem krótki, łatwy i czytelny przykład, aby pokazać, jak obietnice działają z ajaxem.
Proszę spojrzeć na następny przykład . Użyłem
setTimeout
do wyjaśnienia przykład.źródło
Znalazłem prosty sposób, używając
shift()
źródło
Moje rozwiązanie jest następujące
Działało całkiem nieźle. Próbowałem wielu różnych sposobów na zrobienie tego, ale okazało się, że jest to najprostszy i najbardziej wielokrotnego użytku. Mam nadzieję, że to pomoże
źródło
Spójrz na moje rozwiązanie:
1.Włóż tę funkcję (i zmienną) do pliku javascript:
2.Zbuduj tablicę ze swoimi żądaniami:
3. Utwórz funkcję oddzwaniania:
4. Wywołaj funkcję runFunctionQueue z parametrami:
źródło
$.when
nie działa dla mnie,callback(x)
zamiastreturn x
działać zgodnie z opisem tutaj: https://stackoverflow.com/a/13455253/10357604źródło
Wypróbuj w ten sposób utwórz pętlę wewnątrz funkcji skryptu Java, aby poczekać, aż zakończy się wywołanie ajax.
źródło
setTimeout()
NIEtake a sleep
. W takim przypadku po prostu blokujesz wszystkie karty, aż staniedone
się prawdą.done
nigdy nie będzie to prawdą, dopóki pętla while będzie nadal działać. Jeśli pętla while jest uruchomiona, pętla zdarzeń nie może być kontynuowana i dlatego nigdy nie uruchomi wywołania zwrotnego do sukcesu ajax.