Jak mogę odrzucić obietnicę zwróconą przez funkcję asynchroniczną / oczekującą?
np. pierwotnie
foo(id: string): Promise<A> {
return new Promise((resolve, reject) => {
someAsyncPromise().then((value)=>resolve(200)).catch((err)=>reject(400))
});
}
Przetłumacz na async / czekaj
async foo(id: string): Promise<A> {
try{
await someAsyncPromise();
return 200;
} catch(error) {//here goes if someAsyncPromise() rejected}
return 400; //this will result in a resolved promise.
});
}
Jak mogę właściwie odrzucić tę obietnicę w tym przypadku?
Promise
konstruktora antipattern ! Nawet pierwszy fragment powinien zostać napisanyfoo(id: string): Promise<A> { return someAsyncPromise().then(()=>{ return 200; }, ()=>{ throw 400; }); }
Odpowiedzi:
Najprościej jest
throw
wError
opakowaniu wartość, co powoduje przerwanie obietnicy zError
opakowania wartość:Możesz także podać tylko
throw
wartość, ale wtedy nie ma informacji o śledzeniu stosu:Alternatywnie, zwróć odrzuconą obietnicę z
Error
zawijaniem wartości, ale nie jest to idiomatyczne:(Lub po prostu
return Promise.reject(400);
, ale znowu, wtedy nie ma informacji kontekstowych.)(W twoim przypadku, gdy używasz,
TypeScript
afoo
wartość pobierana toPromise<A>
, należy użyćreturn Promise.reject<A>(400 /*or error*/);
)W sytuacji
async
/await
to ostatnie jest prawdopodobnie semantycznym niedopasowaniem, ale działa.Jeśli rzucisz an
Error
, to gra dobrze z czymkolwiek, co pochłaniafoo
wynik wawait
składni:źródło
throw
jest lepszy niżPromise.reject()
IMO. Czythrow 400
to inne pytanie. W PO odrzuca 400, a my możemy argumentować, żeError
zamiast tego powinien odrzucić .async
funkcjach nie maresolve
lub nie mareject
funkcji. Sąreturn
ithrow
, które są idiomatycznymi sposobami rozwiązania i odrzuceniaasync
obietnicy funkcji.new
to wyraźnie. Pamiętaj też, że nie możesz tego pominąć, jeśli maszError
podklasę (class MyError extends Error
), więc ...Prawdopodobnie należy również wspomnieć, że można po prostu
catch()
połączyć funkcję po wywołaniu operacji asynchronicznej, ponieważ pod maską nadal jest zwracana obietnica.W ten sposób możesz uniknąć
try/catch
składni, jeśli Ci się nie podoba.źródło
async
funkcję, rzucam wyjątek, a następnie ładnie go łapię,.catch()
tak jak gdybym wróciłPromise.reject
lub zadzwoniłreject
. Lubię to!await
błędy w jednej procedurze. O ile nie są potrzebne bardzo konkretne przypadki dla każdegoawait
, nie rozumiem, dlaczego chcesz je tak złapać. Tylko ja pokorna opinia.await
awarię osobno, ale także musiałem pracować z ramami opartymi na obietnicach, które odrzucały obietnice błędu.${host}/user/permissions/repositories_wrong_url/
, accessToken, accessTokenSecret) .catch (err => {logger.error ('Nie można pobrać uprawnień do repozytorium', err); callback (err);})await
tutaj słowa kluczowego.Możesz utworzyć funkcję opakowania, która przyjmuje obietnicę i zwraca tablicę z danymi, jeśli nie ma błędu, i błędem, jeśli wystąpił błąd.
Użyj tego w ES7 i w funkcji asynchronicznej :
źródło
Lepszym sposobem na napisanie funkcji asynchronicznej byłoby zwrócenie oczekującej obietnicy od początku, a następnie obsługa zarówno odrzucania, jak i rozstrzygania w ramach wywołania zwrotnego obietnicy, zamiast tylko wyrzucania odrzuconej obietnicy w przypadku błędu. Przykład:
Następnie po prostu połącz metody ze zwróconej obietnicy:
Źródło - ten samouczek:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise
źródło
Mam sugestię, aby właściwie obsługiwać odrzucenia w nowatorskim podejściu, bez posiadania wielu bloków try-catch.
Skąd należy importować funkcję to.ts :
Kredyty trafiają do Dimy Grossman pod poniższym linkiem .
źródło
let [err]=
wtedy, gdy sprawdzane są błędy.To nie jest odpowiedź na odpowiedź @TJ Crowder. Po prostu komentarz odpowiadający na komentarz „I faktycznie, jeśli wyjątek zostanie przekształcony w odrzucenie, nie jestem pewien, czy tak naprawdę przeszkadza mi, jeśli jest to Błąd. Moje powody rzucania tylko błędu prawdopodobnie nie mają zastosowania. „
jeśli twój kod używa
async
/await
, nadal dobrą praktyką jest odrzucanie za pomocąError
zamiast400
:źródło
Wiem, że jest to stare pytanie, ale natknąłem się na wątek i wydaje się, że istnieje tutaj związek między błędami a odrzuceniem, który działa w wielu przypadkach (przynajmniej w wielu przypadkach) często powtarzanej porady, aby nie używać obsługi wyjątków do zajmować się przewidywanymi przypadkami. Przykład: jeśli metoda asynchroniczna próbuje uwierzytelnić użytkownika, a uwierzytelnienie nie powiedzie się, jest to odrzucenie (jeden z dwóch przewidywanych przypadków), a nie błąd (np. Jeśli interfejs API uwierzytelniania był niedostępny).
Aby upewnić się, że nie tylko dzielę włosy, przeprowadziłem test wydajności trzech różnych podejść, używając tego kodu:
Niektóre rzeczy, które tam są, są zawarte z powodu mojej niepewności co do interpretera Javascript (lubię schodzić tylko do jednej dziury królika na raz); na przykład, zawarłem
doSomething
funkcję i przypisałem jej zwrot, abydummyValue
mieć pewność, że bloki warunkowe nie zostaną zoptymalizowane.Moje wyniki to:
Wiem, że istnieje wiele przypadków, w których polowanie na małe optymalizacje nie jest warte kłopotu, ale w systemach na większą skalę te rzeczy mogą mieć dużą kumulatywną różnicę, i jest to dość surowe porównanie.
SO… chociaż myślę, że podejście przyjęte w odpowiedzi jest słuszne w przypadkach, w których oczekujesz, że będziesz musiał poradzić sobie z nieprzewidywalnymi błędami w funkcji asynchronicznej, w przypadkach, gdy odrzucenie oznacza po prostu „musisz przejść do planu B (lub C lub D…) „Myślę, że preferuję odrzucenie przy użyciu niestandardowego obiektu odpowiedzi.
źródło