Strumienie danych i zażądanie nimi to chleb powszedni dla programistów pracujących z Angularem. Z pomocą przychodzi nam tutaj biblioteka RxJS i jej operator „retry” o którym opowiem dzisiaj szerzej w moim wpisie.
Czym jest operator 'retry'
?
Operator retry w RxJS pozwala na ponowienie subskrypcji do strumienia, który generuje błąd. Gdy w strumieniu wystąpi błąd, operacja retry automatycznie ponowi subskrypcję do źródła, co może być niezwykle przydatne w przypadku awaryjnych sytuacji, takich jak problemy sieciowe.
Daje nam jeszcze możliwość implementacji dodatkowego kodu, który wykona się przed ponową subskrypcją.
Przykład użycia
Rozważmy prosty przykład, w którym pobieramy dane z serwera za pomocą HttpClient
i chcemy ponowić próbę w przypadku wystąpienia błędu.
import {inject, Injectable} from '@angular/core';
import {HttpClient} from "@angular/common/http";
import {retry, timer} from "rxjs";
@Injectable({
providedIn: 'root'
})
export class ApiService {
private httpClient = inject(HttpClient)
getData() {
const url = 'google.pl';
return this.httpClient.get(url).pipe(retry(3));
}
}
W celach testowych ustawiłem pierwszy lepszy url, który przyszedł mi do głowy. Po implementacji powyższego kodu w konsoli z requestami sieciowymi zobaczymy łącznie cztery próby wykonania się requestu typu get. Cztery próby ponieważ jedna próba jest wykonywana na początku a 3 to ponowienia, które ustawiliśmy w konfiguracji pipa retry. Oczywiście wszystkie zakończą się niepowodzeniem z racji niepoprawnego adresu.
Jeśli chcielibyśmy zaimplementować specyficzną logikę w zależności od np. kodu błędu to jak najbardziej jest taka możliwość. Jak widać na poniższym przykładzie mamy dostęp do obiektu error, który zawiera wszystkie potrzebne informacje:
getData() {
const url = 'google.pl';
return this.httpClient.get(url).pipe(retry({
count: 3, delay: (error, retryCount) => {
// twój kod
return timer(1000)
}
}));
}
Co jeśli chciałbym przerwać ponawianie?
Załóżmy, że jest taki przypadek, w którym już nie chcemy próbować ponownie i przestać ponawiać request – jak najbardziej jest taka możliwość, musimy tylko zwrócić observable z błędem jak przykładowo zrobiłem to poniżej:
getData() {
const url = 'google.pl';
return this.httpClient.get(url).pipe(retry({
count: 3, delay: (error, retryCount) => {
if (retryCount === 2) {
return throwError(() => error)
}
return timer(1000)
}
}));
}
Podsumowanie
Operator „retry” w RxJS jest niezwykle przydatnym narzędziem do zarządzania błędami w strumieniach danych. Pozwala on na automatyczne ponowienie subskrypcji do źródła danych w przypadku wystąpienia błędu oraz dodanie dodatkowej logiki, która być może rozwiąże problem 🙂
Dzięki za przeczytanie i miłego dnia!