Wskazówka: używaj tylko, first()
jeśli:
- Uważasz, że zero wyemitowanych elementów jest warunkiem błędu (np. Ukończenie przed emisją) ORAZ jeśli istnieje większe niż 0% prawdopodobieństwo błędu, radzisz sobie z nim wdzięcznie
- LUB Wiesz w 100%, że źródło, które można zaobserwować, wyemituje 1+ przedmiotów (więc nigdy nie możesz rzucać) .
Jeśli emisje są zerowe i nie obsługujesz ich bezpośrednio (z catchError
), ten błąd zostanie propagowany, prawdopodobnie spowoduje nieoczekiwany problem w innym miejscu i może być dość trudny do wyśledzenia - zwłaszcza jeśli pochodzi od użytkownika końcowego.
W większości przypadków bezpieczniej jest używać, take(1)
pod warunkiem, że:
- Nie musisz
take(1)
nic emitować, jeśli źródło zakończy się bez emisji.
- Nie musisz używać predykatu wbudowanego (np.
first(x => x > 10)
)
Uwaga: Można użyć predykatu z take(1)
tak: .pipe( filter(x => x > 10), take(1) )
. Nie ma błędu, jeśli nic nie jest większe niż 10.
Co powiesz na single()
Jeśli chcesz być jeszcze bardziej rygorystyczny i nie zezwalać na dwie emisje, możesz użyć single()
których błędów, jeśli są emisje zerowe lub 2+ . W takim przypadku znowu będziesz musiał obsłużyć błędy.
Wskazówka: Single
czasami może się przydać, jeśli chcesz mieć pewność, że twój obserwowalny łańcuch nie wykonuje dodatkowej pracy, takiej jak dwukrotne wywołanie usługi http i emisja dwóch obserwowalnych. Dodanie single
na końcu rury poinformuje Cię, jeśli popełniłeś taki błąd. Używam go w 'module uruchamiającym zadania', w którym przekazujesz obserwowalne zadanie, które powinno emitować tylko jedną wartość, więc przekazuję odpowiedź, single(), catchError()
aby zagwarantować dobre zachowanie.
Dlaczego nie zawsze używać first()
zamiast take(1)
?
znany jako. Jak first
potencjalnie może powodować więcej błędów?
Jeśli masz obiekt obserwowalny, który pobiera coś z usługi, a następnie przesyła go przez kanał, przez first()
większość czasu powinno być dobrze. Ale jeśli ktoś przyjdzie, aby wyłączyć usługę z jakiegokolwiek powodu - i zmieni ją na emisję, of(null)
albo NEVER
każdy dalszy first()
operator zacznie rzucać błędy.
Teraz zdaję sobie sprawę, że może to być dokładnie to, czego chcesz - dlatego to tylko wskazówka. Operator first
zaapelował do mnie, ponieważ brzmiał nieco mniej „niezgrabnie” niż, take(1)
ale trzeba uważać z obsługą błędów, jeśli jest szansa, że źródło nie emituje. Zależy to całkowicie od tego, co robisz.
Jeśli masz wartość domyślną (stałą):
Zastanów się również, .pipe(defaultIfEmpty(42), first())
czy masz wartość domyślną, której należy użyć, jeśli nic nie jest emitowane. To oczywiście nie spowodowałoby błędu, ponieważ first
zawsze otrzymywałoby wartość.
Zauważ, że defaultIfEmpty
jest wyzwalane tylko wtedy, gdy strumień jest pusty, a nie, jeśli wartość tego, co jest emitowane, wynosi null
.
first()
itake()
są w ogóle takie same, co myślę, że jest oczywiste, tylko tofirst()
itake(1)
są takie same. Nie jestem pewien z Twojej odpowiedzi, czy uważasz, że nadal istnieje różnica?