Découvrez pourquoi les Observables restent indispensables à l'ère des Signals, et maîtrisez leurs concepts clés (subscribe, pipe, switchMap) pour une gestion efficace des flux de données en JavaScript, illustrés par des exemples pratiques.
"Les Signals sont là, est-ce que ça vaut encore le coup de comprendre les Observables ?"
Cette question, je l'entends souvent. Et la réponse est simple : AB-SO-LU-MENT.
Avec les Signals, on peut aussi le faire ! La syntaxe est différente, mais chaque approche a ses avantages. Les Observables brillent particulièrement quand on doit jongler avec des flux d'événements et des transformations complexes. Si vous n’êtes pas convaincus, je vous invite à lire cet article de mon collègue Léo.
Quand j'étais petite, je voulais devenir plombier. OK, c'est faux. Mais aujourd'hui, je suis un peu plombière de temps en temps. D'abord pour déboucher mon évier (merci la coloc), mais surtout quand je manipule des Observables.
Si vous pensez que les Observables sont juste une façon compliquée de faire des callbacks, laissez-moi vous montrer pourquoi ils restent indispensables en 2025.
Imaginez un observable comme un flux d'eau ou plutôt de glaçons dans un tuyau. Il peut émettre une série de valeurs au fil du temps, telles que des clics de souris, des réponses de serveur, ou même des mises à jour en temps réel.
La question qu’on se pose c’est comment correctement récupérer les glaçons qui sont dans notre tuyau ?
Plic ploc, d’abord, on commence par créer la plomberie. C’est le moment où vous définissez un flux observable, par exemple en utilisant of
, fromEvent
, ou interval
. Le robinet est en place, mais rien ne coule encore.
subscribe
: Le Point de ConsommationSplash ! Avec subscribe
, vous tournez la poignée et l’eau commence à couler.
Le subscribe
est comme un évier où l'eau finit par se retrouver. Il est le point de terminaison de votre flux d'observables. Mais plus important, il “ouvre le flux”. Sans subscribe on ne commence jamais l’écoute. Lorsque vous vous abonnez à un observable, vous commencez à recevoir les données qu'il émet. Sans évier, on n’ouvre pas le robinet !
Mais attention, un subscribe
sans unsubscribe
, c'est comme partir en vacances en laissant le robinet ouvert. Sauf qu'au lieu d'une facture d'eau salée, vous aurez droit à des memory leaks et des bugs mystérieux à 2h du matin.
pipe
: Le Tuyau de ConnexionLe pipe
, c'est le tuyau magique qui transforme votre eau boueuse en eau potable. Le pipe
permet de connecter différents opérateurs pour transformer ou filtrer les données d'un observable avant qu'elles n'atteignent votre application.
tap
: L'Inspection du FluxQuand vous voulez observer ce qui se passe dans le flux d'observable sans le modifier, tap
est votre outil. Comme un regard qui permet d'inspecter les données sans les altérer, tap
vous permet d'effectuer des actions secondaires, telles que le déclenchement d'effets secondaires non liés à la transformation des données elles-mêmes.
map
: La Transformation du FluxL'opérateur map
agit comme un mutation qui transforme chaque goutte d'eau (ou donnée) passant à travers. Par exemple, si vous recevez une liste d'objets et que vous souhaitez extraire une propriété spécifique de chaque objet, map
vous permet de transformer chaque élément de la liste en cette propriété spécifique.
switchMap
: La Réorganisation du FluxVoyez ça comme une bouche d’évacuation suivie d’un autre robinet. Quand les glaçons arrivent, ils rentrent dans le premier tuyau. Si d’autres premiers glaçons arrivent, le contenu actuel est vidangé.
C'est particulièrement utile quand votre utilisateur clique comme un possédé sur le bouton "Rafraîchir". Au lieu d'avoir 42 requêtes qui se battent en duel, switchMap
fait le ménage : seule la dernière requête survit. Les autres ? Direct à la benne !
💡 mergeMap
: Laisse toutes les requêtes se poursuivre et traite chaque résultat indépendamment, ce qui est utile lorsque chaque action (comme un clic) doit être traitée, même si elles se chevauchent.
combineLatest
: La Fusion de Flux SynchronisésL'opérateur combineLatest
est comme un collecteur qui rassemble plusieurs flux d'eau et les synchronise pour former un seul flux combiné. Cet opérateur attend que chaque observable ait émis au moins une valeur, puis il combine les dernières valeurs émises de chaque observable en une seule émission.
Imaginez que vous avez plusieurs tuyaux qui amènent chacun un glaçon de couleur différente : combineLatest
vous permettrait de créer un glaçon multicolore à partir de tous ces tuyaux. C'est utile, par exemple, lorsque vous voulez synchroniser plusieurs sources de données avant de procéder à une action.
take
: La Limitation du Fluxscreeeech Soit le réservoir est vide (complétion), soit vous criez "STOP !" avec unsubscribe
ou take
. Dans tous les cas, on range les outils, on nettoie le chantier avec finalize
, et on s'assure qu'il n'y a pas de fuite sous l'évier !
take
, c'est comme ces minuteurs de douche économes : "Tu veux 3 valeurs ? Tu en auras 3, pas une de plus !" C'est le champion des économies d'eau... euh, de données. Par exemple, vous pouvez utiliser take(3)
pour ne traiter que les trois premières réponses d'une série de requêtes HTTP.
Si take
est le minuteur de douche, takeUntil
est le détecteur de mouvement qui coupe l'eau quand vous sortez de la salle de bain.
Il existe d’autres opérateurs comme takeUntil
. Par exemple le nouveau takeUntilDestroy
de Angular 16 (cf cet article). D’autres sont à explorer dans cet article de notre blog !
finalize
: Le Nettoyage du FluxLe finalize
est le processus de fermeture du robinet et de nettoyage après avoir utilisé le flux d'eau. Cet opérateur vous permet d'exécuter du code de nettoyage ou des actions finales une fois que l'observable a complété ou a été annulé.
Finalement, les Observables, c'est comme la plomberie : quand c'est bien fait, personne n'y pense. Quand c'est mal fait, ça se remarque rapidement.Finalement, un bon plombier n'est pas celui qui répare les fuites, c'est celui qui les évite.Je vous laisse avec une petite check-list du bon plombier observable
takeUntil
ou gérer manuellement vos subscriptionstake(1)
pour les one-shotcatchError
pour gérer les erreurs (les fuites, c'est jamais joli)switchMap
pour les requêtes qui s'annulentngOnDestroy