Mam kod, który wygląda mniej więcej tak w javascript:
forloop {
//async call, returns an array to its callback
}
Po wykonaniu WSZYSTKICH wywołań asynchronicznych chcę obliczyć min dla wszystkich tablic.
Jak mogę czekać na nich wszystkich?
Moim jedynym pomysłem w tej chwili jest mieć tablicę wartości logicznych o nazwie done i ustawić done [i] na true w i-tej funkcji zwrotnej, a następnie powiedzieć while (nie wszystkie są gotowe) {}
edit: Przypuszczam, że jednym możliwym, ale brzydkim rozwiązaniem byłoby edytowanie gotowej tablicy w każdym wywołaniu zwrotnym, a następnie wywołanie metody, jeśli wszystkie inne gotowe są ustawione z każdego wywołania zwrotnego, a zatem ostatnie wywołanie zwrotne do zakończenia wywoła metodę kontynuacji.
Z góry dziękuję.
javascript
asynchronous
codersarepeople
źródło
źródło
while (not all are done) { }
nie zadziała. Gdy jesteś zajęty czekaniem, żadne z Twoich oddzwonień nie może działać.Odpowiedzi:
Nie byłeś zbyt szczegółowy w swoim kodzie, więc wymyślę scenariusz. Powiedzmy, że masz 10 wywołań Ajax i chcesz zebrać wyniki z tych 10 wywołań AJAX, a gdy wszystkie się zakończą, chcesz coś zrobić. Możesz to zrobić w ten sposób, gromadząc dane w tablicy i śledząc, kiedy zakończy się ostatnia:
Licznik ręczny
Uwaga: obsługa błędów jest tutaj ważna (nie jest wyświetlana, ponieważ jest specyficzna dla sposobu wykonywania połączeń Ajax). Będziesz chciał pomyśleć o tym, jak poradzisz sobie z przypadkiem, gdy jedno wywołanie ajax nigdy się nie kończy, albo z błędem, albo utknie na długi czas lub po długim czasie upłynie.
jQuery Promises
Dodając do mojej odpowiedzi w 2014 roku. Obecnie obietnice są często używane do rozwiązywania tego typu problemów, ponieważ jQuery
$.ajax()
już zwraca obietnicę i$.when()
poinformuje Cię, kiedy grupa obietnic zostanie rozwiązana, i zbierze wyniki zwrotu:Standardowe obietnice ES6
Jak określono w odpowiedzi kba : jeśli masz środowisko z wbudowanymi natywnymi obietnicami (nowoczesna przeglądarka lub node.js lub używając babeljs transpile lub używając wypełnienia obietnicy), możesz użyć obietnic określonych w ES6. Zobacz tę tabelę, aby uzyskać informacje o obsłudze przeglądarek. Obietnice są obsługiwane w prawie wszystkich obecnych przeglądarkach, z wyjątkiem IE.
Jeśli
doAjax()
zwróci obietnicę, możesz to zrobić:Jeśli chcesz wykonać operację asynchroniczną niezwiązaną z obietnicą w taką, która zwraca obietnicę, możesz ją „obiecać” w następujący sposób:
Następnie użyj powyższego wzoru:
Bluebird obiecuje
Jeśli używasz bogatszej w funkcje biblioteki, takiej jak biblioteka obietnic Bluebird , ma ona wbudowane dodatkowe funkcje, które to ułatwiają:
źródło
doAjax()
opcję, która zwraca obietnicę jako jedną z opcji. To samo cofetch()
.Meldowanie od 2015 roku: mamy teraz natywne obietnice w najnowszej przeglądarce (Edge 12, Firefox 40, Chrome 43, Safari 8, Opera 32 i Android 4.4.4 i iOS Safari 8.4, ale nie Internet Explorer, Opera Mini i starsze wersje systemu Android).
Jeśli chcemy wykonać 10 akcji asynchronicznych i otrzymać powiadomienie o zakończeniu wszystkich, możemy skorzystać z natywnej
Promise.all
, bez żadnych zewnętrznych bibliotek:źródło
Promises.all()
powinno byćPromise.all()
.Promise.all()
co nie obejmuje aktualnych wersji IE.Można użyć jQuery odroczony obiektu wraz z , gdy metody.
źródło
jQuery
co zwykle oznacza, że operator operacyjny nie chciał odpowiedzi jQuery.Możesz to naśladować w ten sposób:
to każde wywołanie asynchroniczne robi to:
podczas gdy w każdym wywołaniu asynchronicznym na końcu metody dodajesz tę linię:
Innymi słowy, emulujesz funkcję odliczania w dół.
źródło
To moim zdaniem najbardziej zgrabny sposób.
Promise.all
FetchAPI
(z jakiegoś powodu Array.map nie działa dla mnie wewnątrz funkcji .then. Ale możesz użyć .forEach i [] .concat () lub czegoś podobnego)
źródło
return responses.map(response => { return response.json(); })
, lubreturn responses.map(response => response.json())
.Użyj biblioteki przepływu sterowania, takiej jak
after
źródło