Subject et BehaviorSubject : deux frères acrobates dans le monde de la programmation réactive
\n\nSi vous avez déjà jeté un œil sur Stack Overflow à la discussion « What is the difference between Subject and BehaviorSubject? », vous savez que ce sujet attire des milliers de vues. Et ce n'est pas étonnant — c'est l'une de ces questions qui se pose tôt ou tard à chaque développeur travaillant avec RxJS en TypeScript.
\n\nImaginez que vous gérez une diffusion en direct de données. Subject est comme un micro ouvert : celui qui s'abonne en premier reçoit tout ce qui sera dit ensuite. BehaviorSubject, quant à lui, est un micro qui garde toujours la dernière phrase et la répète immédiatement à un nouvel auditeur. Vous sentez la différence ?
\n\nDans cet article, nous ne nous contenterons pas de répéter la documentation. Nous analyserons des cas réels, montrerons des exemples de code en TypeScript et donnerons des règles claires pour faire votre choix. C'est parti !
\n\nQu'est-ce que Subject en TypeScript ?
\n\nSubject est un type spécial d'Observable qui est également un observateur (Observer). Il peut recevoir des données via la méthode next() et les distribuer à tous les abonnés. Mais il y a un détail important : Subject ne stocke pas les valeurs précédentes.
Un exemple simple en TypeScript :
\n\nimport { Subject } from 'rxjs';\n\nconst subject = new Subject<string>();\n\n// On s'abonne après que les données aient déjà été envoyées\nsubject.next('Premier message');\nsubject.next('Deuxième message');\n\n// Cet abonné ne recevra rien\nsubject.subscribe({\n next: (value) => console.log('Abonné :', value)\n});\n\n// Celui-ci sera visible\nsubject.next('Troisième message');\n\n\nQue s'affichera-t-il dans la console ? Seulement « Abonné : Troisième message ». Les deux premiers messages sont perdus à jamais pour cet abonné. Cet effet est appelé « démarrage à froid » — vous ne recevez que les données envoyées après l'abonnement.
\n\nBehaviorSubject : quand il faut se souvenir du passé
\n\nBehaviorSubject est le même Subject, mais avec un super-pouvoir : il stocke toujours la dernière valeur et la fournit immédiatement au nouvel abonné lors de l'abonnement. Une condition obligatoire : il faut spécifier une valeur initiale.
\n\nimport { BehaviorSubject } from 'rxjs';\n\nconst behaviorSubject = new BehaviorSubject<string>('Valeur initiale');\n\n// On s'abonne — on reçoit immédiatement la dernière valeur\nbehaviorSubject.subscribe({\n next: (value) => console.log('Premier abonné :', value)\n});\n\nbehaviorSubject.next('Première mise à jour');\nbehaviorSubject.next('Deuxième mise à jour');\n\n// Cet abonné recevra 'Deuxième mise à jour' immédiatement\nbehaviorSubject.subscribe({\n next: (value) => console.log('Deuxième abonné :', value)\n});\n\n\nAffichage dans la console :
\nPremier abonné : Valeur initiale\nPremier abonné : Première mise à jour\nPremier abonné : Deuxième mise à jour\nDeuxième abonné : Deuxième mise à jour\n\n\nVous voyez ? Le deuxième abonné a immédiatement reçu la dernière valeur, bien qu'il se soit abonné plus tard. C'est la différence clé entre BehaviorSubject et Subject.
\n\nComparaison Subject et BehaviorSubject : tableau des différences
\n\nRésumons toutes les différences dans un tableau clair qui vous sera utile lors d'un entretien ou dans un projet réel.
\n\n- \n
- Valeur initiale : Subject — non. BehaviorSubject — obligatoire. \n
- Stockage de la dernière valeur : Subject — ne stocke pas. BehaviorSubject — stocke et fournit au nouvel abonné. \n
- Comportement en cas d'abonnement tardif : Subject — ignore tous les événements précédents. BehaviorSubject — fournit la dernière valeur. \n
- Utilisation avec Angular : Subject — pour les événements (clics, minuteurs). BehaviorSubject — pour l'état (données utilisateur, paramètres). \n
- Méthode getValue() : Subject — absente. BehaviorSubject — existe, retourne la valeur actuelle de manière synchrone. \n