Więc w zasadzie pytasz, jaka jest różnica między tymi dwoma (gdzie p
jest obietnica utworzona z jakiegoś poprzedniego kodu):
return p.then(...).catch(...);
i
return p.catch(...).then(...);
Istnieją różnice, gdy p rozwiązuje lub odrzuca, ale to, czy te różnice mają znaczenie, czy nie, zależy od tego, co robi kod wewnątrz .then()
lub .catch()
procedury obsługi.
Co się stanie, gdy zostanie p
rozwiązany:
W pierwszym schemacie, po p
rozwiązaniu, .then()
wywoływana jest procedura obsługi. Jeśli ten .then()
program obsługi zwróci wartość lub inną obietnicę, która ostatecznie zostanie rozwiązana, wówczas .catch()
procedura obsługi jest pomijana. Ale jeśli przewodnik .then()
albo wyrzuci lub zwróci obietnicę, która ostatecznie ją odrzuci, wówczas program .catch()
obsługi wykona zarówno odrzucenie w pierwotnej obietnicy p
, jak i błąd, który wystąpi w programie .then()
obsługi.
W drugim schemacie, po p
rozwiązaniu, .then()
wywoływana jest procedura obsługi. Jeśli ten przewodnik .then()
rzuca lub zwraca obietnicę, która ostatecznie odrzuca, .catch()
nie może jej złapać, ponieważ znajduje się przed nią w łańcuchu.
Więc to jest różnica # 1. Jeśli program .catch()
obsługi jest AFTER, może również wychwycić błędy wewnątrz .then()
obsługi.
Co się dzieje, gdy p
odrzuca:
Teraz, w pierwszym schemacie, jeśli obietnica zostanie p
odrzucona, to program .then()
obsługi jest pomijany, a program .catch()
obsługi zostanie wywołany tak, jak można się tego spodziewać. To, co robisz w .catch()
procedurze obsługi, określa, co zostanie zwrócone jako wynik końcowy. Jeśli po prostu zwrócisz wartość z .catch()
procedury obsługi lub zwrócisz obietnicę, która w końcu zostanie rozwiązana, wówczas łańcuch obietnic przełącza się do stanu rozwiązanego, ponieważ „obsłużyłeś” błąd i powróciłeś normalnie. Jeśli wyrzucisz lub zwrócisz odrzuconą obietnicę do przewodnika .catch()
, wówczas zwrócona obietnica pozostaje odrzucona.
W drugim schemacie, jeśli obietnica zostanie p
odrzucona, .catch()
wywoływany jest przewodnik. Jeśli zwrócisz normalną wartość lub obietnicę, która ostatecznie zostanie rozwiązana przez .catch()
procedurę obsługi (w ten sposób „obsłuży” błąd), wówczas łańcuch obietnicy przełącza się do stanu rozwiązanego, a .then()
procedura obsługi po zakończeniu .catch()
zostanie wywołana.
Więc to jest różnica # 2. Jeśli .catch()
procedura obsługi jest PRZED, to może obsłużyć błąd i pozwolić, aby .then()
procedura obsługi nadal była wywoływana.
Kiedy używać których:
Użyj pierwszego schematu, jeśli chcesz, aby tylko jeden .catch()
program obsługi mógł wychwycić błędy w oryginalnej obietnicy p
lub w .then()
module obsługi, a odrzucenie z programu p
powinno pominąć .then()
procedurę obsługi.
Użyj drugiego schematu, jeśli chcesz być w stanie wychwycić błędy w pierwotnej obietnicy p
i być może (w zależności od warunków), pozwolić łańcuchowi obietnic na kontynuację po rozwiązaniu, wykonując w ten sposób .then()
procedurę obsługi.
Druga opcja
Jest jeszcze jedna opcja korzystania z obu wywołań zwrotnych, do których możesz przejść .then()
jak w:
p.then(fn1, fn2)
Gwarantuje to, że tylko jeden z fn1
lub fn2
kiedykolwiek zostanie wywołany. Jeśli p
ustąpi, fn1
zostanie wezwany. Jeśli p
odrzuci, fn2
zostanie wezwany. Żadna zmiana wyniku fn1
nie może sprawić, fn2
że ktoś Cię wezwie lub odwrotnie. Tak więc, jeśli chcesz mieć absolutną pewność, że tylko jeden z twoich dwóch programów obsługi jest wywoływany, niezależnie od tego, co dzieje się w samych modułach obsługi, możesz użyć p.then(fn1, fn2)
.