Byłem bardzo podekscytowany Promises odkąd zostały one wprowadzone rok temu. Chociaż istnieje wiele postów i opinii na ten temat, obietnice nie sprawią, że twój kod będzie bardziej wydajny… sprawią, że będzie on łatwiejszy do odczytania i zrozumienia (co w mojej książce, często liczy się o wiele bardziej!)
W pierwszej części tego postu, wyjaśnię podstawową strukturę obietnic. Jeśli masz już to ogarnięte, nie krępuj się przewinąć do drugiej połowy posta.
Promises explained in plain english
Oto podstawowa struktura obietnicy w Javascript:
Pretty typowy (i nieuchwytny) wycinek kodu. Postaram się rozbić to, co się dzieje.
Na początek skup się tylko na liniach 1-15:
- Tam jest instancja. Ta linia w zasadzie tworzy obietnicę. Obietnica w JS potrzebuje czegoś do zrobienia, zadania. Więc funkcja, którą widzisz przekazywana tutaj – function (resolve,reject) {…} jest tym zadaniem
- Następnie widzisz ciało zadania. Możesz tutaj robić różne rzeczy. Gdzieś w tym bloku kodu musisz zdecydować, czy rzeczy poszły dobrze, czy nie. Na przykład, jeśli używałeś tej przestrzeni do pobrania obrazu, albo go otrzymałeś (poszło dobrze)… albo nie (nie tak dobrze).
- Jeśli rzeczy poszły dobrze, wywołasz jakąś funkcję, która oznaczy tę obietnicę jako „rozwiązaną”. Jeśli rzeczy nie poszły zgodnie z planem, „odrzucisz” tę obietnicę. (porozmawiamy o tym bardziej szczegółowo za chwilę)
Teraz skupmy się na pozostałej części wycinka kodu, liniach 17-27:
- Do tej pory, w liniach 1-15, tylko zdefiniowałeś swój obiekt Promise
- W liniach 17 & 22, w zasadzie dołączasz do niego handlery
- promise.XXXX (gdzie XXX może być „.then” lub „.catch” itp.) w zasadzie uruchamia funkcję zdefiniowaną w obietnicy (linie 1-15). W zależności od tego, jak sprawy się potoczyły (rozwiązane lub odrzucone), będą one wywoływać funkcje odpowiednio w „.then” i „.catch”. Więc jeśli twoja obietnica została rozwiązana (…wszystko poszło dobrze), funkcja wewnątrz .then(…) zostanie wykonana, w przeciwnym razie funkcja w .catch(…) zostanie wykonana.
NOTE:
- „.then(function)” zwraca obietnicę. Ponadto, na obiektach Promise można wywoływać tylko „.then(…)” lub „.catch(…)”.
Teraz, gdy już poznaliśmy podstawy, przyjrzyjmy się bardziej interesującemu przykładowi tego, co możemy zrobić z obietnicami.
Łączenie obietnic w celu wykonania wielu żądań
Problem: Ostatnio natknąłem się na sytuację, w której potrzebowałem pobrać garść adresów URL jeden po drugim. Jednakże, odpowiedź dla każdego adresu URL musiała być obsługiwana inaczej w oparciu o adres URL.
Na potrzeby tego postu, załóżmy, że pobierane adresy URL to:
- google.com
- apple.com
- amazon.com
Oto uproszczona wersja skryptu, którego użyłem do obsługi tego problemu:
Rozłóżmy to na czynniki pierwsze:
- Linie 1-11: Utwórz prosty wrapper wokół metody AJAX Get udostępnianej przez jQuery. To po prostu przekaże odpowiedź do określonego wywołania zwrotnego.
- Linie 18-51: Następnie tworzę trzy funkcje (tak! Funkcje!), które zwracają JS Promise
- Każda obietnica wewnętrznie robi to – używa wrappera Ajax do pobrania swojego adresu url, a po otrzymaniu danych/odpowiedzi robi coś z danymi i ostatecznie wywołuje „resolve()”
- W linii 54: Łańcuchuję te obietnice jedna po drugiej. Zauważ, że każda z tych funkcji zwraca obietnicę (i nie jest obietnicą samą w sobie). Dlatego używam „first()”.then(…) w przeciwieństwie do „first.then(…)”
Aby wyjaśnić dalej, oto sposób patrzenia na łańcuch obietnic.
W ten sposób można sekwencyjnie uzyskać każdy adres URL, obsłużyć go zgodnie z życzeniem i odpalić funkcję „resolved()”, aby wywołać następną obietnicę w łańcuchu 🙂
Uwaga: jeśli spróbujesz uruchomić powyższy fragment kodu w przeglądarce, będziesz musiał włączyć CORS. Oto rozszerzenie chrome, które może pomóc zrobić to za pomocą prostego kliknięcia.
Mam nadzieję, że podobał Ci się ten post.