Quand dois-je stocker les Subscription
instances et les invoquer unsubscribe()
pendant le cycle de vie NgOnDestroy et quand puis-je simplement les ignorer?
L'enregistrement de tous les abonnements introduit beaucoup de désordre dans le code des composants.
Le Guide du client HTTP ignore les abonnements comme celui-ci:
getHeroes() {
this.heroService.getHeroes()
.subscribe(
heroes => this.heroes = heroes,
error => this.errorMessage = <any>error);
}
Dans le même temps, Route & Navigation Guide dit que:
Finalement, nous naviguerons ailleurs. Le routeur supprimera ce composant du DOM et le détruira. Nous devons nettoyer après nous-mêmes avant que cela se produise. Plus précisément, nous devons nous désinscrire avant que Angular ne détruise le composant. Ne pas le faire pourrait créer une fuite de mémoire.
Nous nous désinscrivons de notre
Observable
dans langOnDestroy
méthode.
private sub: any;
ngOnInit() {
this.sub = this.route.params.subscribe(params => {
let id = +params['id']; // (+) converts string 'id' to a number
this.service.getHero(id).then(hero => this.hero = hero);
});
}
ngOnDestroy() {
this.sub.unsubscribe();
}
angular
rxjs
observable
subscription
angular-component-life-cycle
Sergey Tihon
la source
la source
Subscription
shttp-requests
peut être ignoré, car ils n'appellentonNext
qu'une seule fois puis ils appellentonComplete
. LaRouter
place appelle àonNext
plusieurs reprises et pourrait ne jamais appeleronComplete
(pas sûr à ce sujet ...). Il en va de même pourObservable
s deEvent
s. Donc je suppose que ça devrait l'êtreunsubscribed
.subscribe
lui-même qui alloue potentiellement des ressources en amont.Réponses:
--- Edit 4 - Ressources supplémentaires (2018/09/01)
Dans un récent épisode d' Aventures in Angular, Ben Lesh et Ward Bell discutent des questions concernant comment / quand se désinscrire dans un composant. La discussion commence vers 13 h 05:30.
Ward mentionne
right now there's an awful takeUntil dance that takes a lot of machinery
et Shai Reznik mentionneAngular handles some of the subscriptions like http and routing
.En réponse, Ben mentionne qu'il y a des discussions en ce moment pour permettre aux observables de se connecter aux événements du cycle de vie du composant angulaire et Ward suggère un observable des événements du cycle de vie auquel un composant pourrait souscrire pour savoir quand terminer les observables maintenus en tant qu'état interne du composant.
Cela dit, nous avons surtout besoin de solutions maintenant, voici donc d'autres ressources.
Une recommandation pour le
takeUntil()
modèle du membre de l'équipe principale de RxJs Nicholas Jamieson et une règle tslint pour aider à l'appliquer. https://ncjamieson.com/avoiding-takeuntil-leaks/Package npm léger qui expose un opérateur Observable qui prend une instance de composant (
this
) comme paramètre et se désabonne automatiquement pendantngOnDestroy
. https://github.com/NetanelBasal/ngx-take-until-destroyUne autre variante de ce qui précède avec une ergonomie légèrement meilleure si vous ne faites pas de builds AOT (mais nous devrions tous le faire maintenant). https://github.com/smnbbrv/ngx-rx-collector
Directive personnalisée
*ngSubscribe
qui fonctionne comme un canal asynchrone mais crée une vue intégrée dans votre modèle afin que vous puissiez vous référer à la valeur «non encapsulée» dans votre modèle. https://netbasal.com/diy-subscription-handling-directive-in-angular-c8f6e762697fJe mentionne dans un commentaire au blog de Nicholas que la surutilisation de
takeUntil()
pourrait être un signe que votre composant essaie d'en faire trop et que la séparation de vos composants existants en composants de fonctionnalité et de présentation devrait être envisagée. Vous pouvez ensuite| async
l'Observable à partir du composant Feature dans unInput
composant Presentational, ce qui signifie qu'aucun abonnement n'est nécessaire n'importe où. En savoir plus sur cette approche ici--- Edit 3 - La solution «officielle» (2017/04/09)
J'ai parlé à Ward Bell de cette question à NGConf (je lui ai même montré cette réponse qu'il a dite correcte) mais il m'a dit que l'équipe de documentation pour Angular avait une solution à cette question qui n'est pas publiée (bien qu'ils travaillent à la faire approuver) ). Il m'a également dit que je pouvais mettre à jour ma réponse SO avec la prochaine recommandation officielle.
La solution que nous devrions tous utiliser à l'avenir est d'ajouter un
private ngUnsubscribe = new Subject();
champ à tous les composants qui ont des.subscribe()
appels àObservable
s dans leur code de classe.Nous appelons ensuite
this.ngUnsubscribe.next(); this.ngUnsubscribe.complete();
nosngOnDestroy()
méthodes.La sauce secrète (comme déjà noté par @metamaker ) est d'appeler
takeUntil(this.ngUnsubscribe)
avant chacun de nos.subscribe()
appels qui garantira que tous les abonnements seront nettoyés lorsque le composant sera détruit.Exemple:
Remarque: Il est important d'ajouter l'
takeUntil
opérateur comme dernier pour éviter les fuites avec des observables intermédiaires dans la chaîne de l'opérateur.--- Modifier 2 (28/12/2016)
Source 5
Le tutoriel Angular, le chapitre Routage indique maintenant ce qui suit: "Le routeur gère les observables qu'il fournit et localise les abonnements. Les abonnements sont nettoyés lorsque le composant est détruit, protégeant contre les fuites de mémoire, nous n'avons donc pas besoin de vous désabonner de la route params Observable. " - Mark Rajcok
Voici une discussion sur les problèmes de Github pour les documents Angular concernant Router Observables où Ward Bell mentionne qu'une clarification pour tout cela est en cours.
--- Modifier 1
Source 4
Dans cette vidéo de NgEurope, Rob Wormald dit également que vous n'avez pas besoin de vous désabonner de Router Observables. Il mentionne également le
http
service etActivatedRoute.params
dans cette vidéo de novembre 2016 .--- Réponse originale
TLDR:
Pour cette question, il existe (2) sortes de
Observables
- valeur finie et valeur infinie .http
Observables
produire des valeurs finies (1) et quelque chose comme un DOMevent listener
Observables
produire des valeurs infinies .Si vous appelez manuellement
subscribe
(sans utiliser de canal asynchrone), alorsunsubscribe
depuis l' infiniObservables
.Ne vous inquiétez pas des finis ,
RxJs
prenez soin d'eux.Source 1
J'ai retrouvé une réponse de Rob Wormald dans Angular's Gitter ici .
Il déclare (j'ai réorganisé pour plus de clarté et l'accent est à moi)
Il mentionne également dans cette vidéo YouTube sur Observables que
they clean up after themselves
... dans le contexte d'Observables quicomplete
(comme Promises, qui se terminent toujours parce qu'ils produisent toujours 1 valeur et se terminant - nous ne nous sommes jamais inquiétés de la désinscription de Promises pour nous assurer qu'ils nettoient l'xhr
événement auditeurs, non?).Source 2
Également dans le guide Rangle d'Angular 2, il lit
Quand la phrase
our Observable has a longer lifespan than our subscription
s'applique-t-elle?Elle s'applique lorsqu'un abonnement est créé à l'intérieur d'un composant qui est détruit avant (ou pas «longtemps» avant) la
Observable
fin.Je lis cela comme signifiant que si nous souscrivons à une
http
demande ou à un observable qui émet 10 valeurs et que notre composant est détruit avant que cettehttp
demande ne revienne ou que les 10 valeurs aient été émises, nous sommes toujours d'accord!Lorsque la demande revient ou que la 10e valeur est finalement émise, la tâche
Observable
se termine et toutes les ressources sont nettoyées.Source 3
Si nous regardons cet exemple dans le même guide Rangle, nous pouvons voir que le
Subscription
toroute.params
nécessite ununsubscribe()
car nous ne savons pas quand ceux-params
ci cesseront de changer (en émettant de nouvelles valeurs).Le composant pourrait être détruit en s'éloignant, auquel cas les paramètres d'itinéraire continueront probablement de changer (ils pourraient techniquement changer jusqu'à la fin de l'application) et les ressources allouées en abonnement seraient toujours allouées car il n'y en a pas eu
completion
.la source
complete()
en lui-même ne semble pas nettoyer les abonnements. Quelle que soit la manière d'appelernext()
et ensuitecomplete()
, je croistakeUntil()
que s'arrête uniquement lorsqu'une valeur est produite, et non lorsque la séquence est terminée.Subject
intérieur d'un composant et en le basculantngIf
pour déclencherngOnInit
etngOnDestroy
montre que le sujet et ses abonnements ne se termineront jamais ou ne seront jamais supprimés (connecté unfinally
opérateur à l'abonnement). Je dois appelerSubject.complete()
àngOnDestroy
, de sorte que les abonnements peuvent nettoyer après eux - mêmes.takeUnitl
approche, nous ne devons jamais nous désabonner manuellement des observables? Est-ce le cas? De plus, pourquoi devons-nous appelernext()
lengOnDestroy
, pourquoi ne pas simplement appelercomplete()
?Vous n'avez pas besoin d'avoir un tas d'abonnements et de vous désabonner manuellement. Utilisez Subject et takeUntil combo pour gérer les abonnements comme un boss:
Une approche alternative , proposée par @acumartini dans les commentaires , utilise takeWhile au lieu de takeUntil . Vous pouvez le préférer, mais sachez que de cette façon, votre exécution observable ne sera pas annulée lors de la suppression de ng de votre composant (par exemple lorsque vous effectuez des calculs longs ou attendez des données du serveur). La méthode, qui est basée sur takeUntil , n'a pas cet inconvénient et conduit à l'annulation immédiate de la demande. Merci à @AlexChe pour une explication détaillée dans les commentaires .
Voici donc le code:
la source
takeUntil
ettakeWhile
. Le premier se désabonne de la source observable immédiatement lorsqu'il est renvoyé, tandis que le dernier se désabonne uniquement dès que la valeur suivante est produite par la source observable. Si la production d'une valeur par la source observable est une opération consommatrice de ressources, le choix entre les deux peut aller au-delà de la préférence de style. Voir le plunktakeUntil
vstakeWhile
, cependant, pas pour notre cas spécifique. Lorsque nous devons désinscrire des écouteurs lors de la destruction de composants , nous vérifions simplement la valeur booléenne comme() => alive
danstakeWhile
, donc aucune opération consommatrice de temps / mémoire n'est utilisée et la différence concerne à peu près le style (ofc, dans ce cas spécifique).Observable
, qui extrait en interne de la crypto-monnaie et déclenche unnext
événement pour chaque pièce extraite, et l'extraction d'une de ces pièces prend une journée. AvectakeUntil
nous nous désabonnerons de l'exploitation minière sourceObservable
immédiatement une foisngOnDestroy
appelé lors de la destruction de nos composants. Ainsi, laObservable
fonction d' exploration de données est en mesure d'annuler son fonctionnement immédiatement au cours de ce processus.takeWhile
, dans lengOnDestory
nous définissons simplement la variable booléenne. Mais laObservable
fonction d' exploration peut encore fonctionner jusqu'à un jour, et ce n'est qu'à ce moment-là qu'ellenext
se rendra compte qu'il n'y a pas d'abonnement actif et qu'elle doit annuler.La classe d'abonnement a une fonctionnalité intéressante:
Vous pouvez créer un objet Subscription agrégé qui regroupe tous vos abonnements. Pour ce faire, créez un abonnement vide et ajoutez-y des abonnements à l'aide de sa
add()
méthode. Lorsque votre composant est détruit, il vous suffit de résilier l'abonnement global.la source
takeUntil
approche officielle par rapport à cette approche de collecte des abonnements et d'appelunsubscribe
. (Cette approche me semble beaucoup plus propre.)this.subscriptions
est nullesub = subsciption.add(..).add(..)
car dans de nombreux cas, cela produit des résultats inattendus github.com/ReactiveX/rxjs/issues/2769#issuecomment-345636477Certaines des meilleures pratiques concernant les désabonnements observables dans les composants Angular:
Une citation de
Routing & Navigation
Et en répondant aux liens suivants:
http
observableJ'ai rassemblé certaines des meilleures pratiques concernant les désabonnements observables dans les composants Angular à partager avec vous:
http
le désabonnement observable est conditionnel et nous devons considérer les effets du «rappel d'abonnement» exécuté après la destruction du composant au cas par cas. On sait que angulaire se désabonne et nettoie l'http
observable lui-même (1) , (2) . Bien que cela soit vrai du point de vue des ressources, cela ne raconte que la moitié de l'histoire. Disons que nous parlons d'appeler directement àhttp
partir d'un composant, ethttp
réponse a pris plus de temps que nécessaire, donc l'utilisateur a fermé le composant. lesubscribe()
Le gestionnaire sera toujours appelé même si le composant est fermé et détruit. Cela peut avoir des effets secondaires indésirables et, dans les pires scénarios, laisser l'état de l'application cassé. Il peut également provoquer des exceptions si le code du rappel tente d'appeler quelque chose qui vient d'être supprimé. Cependant, en même temps, ils sont parfois souhaités. Disons que vous créez un client de messagerie et que vous déclenchez un son lorsque l'envoi de l'e-mail est terminé - vous voudriez quand même que cela se produise même si le composant est fermé ( 8 ).AsyncPipe
autant que possible car il se désabonne automatiquement de l'observable lors de la destruction des composants.ActivatedRoute
observables commeroute.params
s'ils étaient abonnés à l'intérieur d'un composant imbriqué (ajouté à l'intérieur de tpl avec le sélecteur de composant) ou dynamique car ils peuvent être abonnés plusieurs fois tant que le composant parent / hôte existe. Pas besoin de vous désinscrire d'eux dans d'autres scénarios comme mentionné dans la citation ci-dessus de laRouting & Navigation
documentation.Remarque: En ce qui concerne les services étendus, c'est-à-dire les fournisseurs de composants, ils sont détruits lorsque le composant est détruit. Dans ce cas, si nous nous abonnons à tout observable à l'intérieur de ce fournisseur, nous devrions envisager de nous désinscrire de celui-ci en utilisant le
OnDestroy
hook de cycle de vie qui sera appelé lorsque le service sera détruit, selon les documents.takeUntil
(3) ou vous pouvez utiliser cenpm
package mentionné à (4) La façon la plus simple de vous désabonner d'Observables dans Angular .FormGroup
observables commeform.valueChanges
etform.statusChanges
Renderer2
service commerenderer2.listen
HostListener
car angular se soucie bien de la suppression des écouteurs d'événements si nécessaire et empêche toute fuite de mémoire potentielle due aux liaisons d'événements.Un bon dernier conseil : si vous ne savez pas si un observable est automatiquement désabonné / terminé ou non, ajoutez un
complete
rappel àsubscribe(...)
et vérifiez s'il est appelé lorsque le composant est détruit.la source
ngOnDestroy
est appelé lorsque le service est fourni à un niveau autre que le niveau racine, par exemple fourni explicitement dans un composant qui est supprimé ultérieurement. Dans ces cas, vous devez vous désinscrire des services observables internesngOnDestroy
, ce qui est toujours appelé lorsque les services sont détruits github.com/angular/angular/commit/...Feel free to unsubscribe anyway. It is harmless and never a bad practice.
et concernant votre question, cela dépend. Si le composant enfant est lancé plusieurs fois (par exemple, ajouté à l'intérieurngIf
ou chargé dynamiquement), vous devez vous désabonner pour éviter d'ajouter plusieurs abonnements au même observateur. Sinon, pas besoin. Mais je préfère me désinscrire à l'intérieur du composant enfant car cela le rend plus réutilisable et isolé de la façon dont il pourrait être utilisé.Ça dépend. Si, en appelant
someObservable.subscribe()
, vous commencez à bloquer certaines ressources qui doivent être libérées manuellement lorsque le cycle de vie de votre composant est terminé, vous devez appelertheSubscription.unsubscribe()
pour éviter une fuite de mémoire.Examinons de plus près vos exemples:
getHero()
renvoie le résultat dehttp.get()
. Si vous examinez le code source angulaire 2 ,http.get()
crée deux écouteurs d'événements:et en appelant
unsubscribe()
, vous pouvez annuler la demande ainsi que les auditeurs:Notez que cela
_xhr
est spécifique à la plate-forme, mais je pense qu'il est prudent de supposer qu'il s'agit d'unXMLHttpRequest()
cas dans votre cas.Normalement, c'est suffisamment de preuves pour justifier un manuel
unsubscribe()
appel . Mais selon cette spécification WHATWG , leXMLHttpRequest()
est sujet au ramasse-miettes une fois qu'il est "terminé", même s'il y a des écouteurs d'événement qui lui sont attachés. Donc je suppose que c'est pourquoi le guide officiel angular 2 ometunsubscribe()
et laisse GC nettoyer les auditeurs.Quant à votre deuxième exemple, cela dépend de l'implémentation de
params
. À ce jour, le guide officiel angulaire ne montre plus de désabonnementparams
. J'ai regardé nouveau src et trouvé queparams
c'était juste un sujet de comportement . Puisqu'aucun écouteur ou temporisateur d'événement n'a été utilisé et qu'aucune variable globale n'a été créée, il devrait être sûr d'omettreunsubscribe()
.L'essentiel de votre question est de toujours appeler
unsubscribe()
une garde contre les fuites de mémoire, sauf si vous êtes certain que l'exécution de l'observable ne crée pas de variables globales, n'ajoute pas d'écouteurs d'événements, ne définit pas de temporisateur ou ne fait rien d'autre qui entraîne des fuites de mémoire .En cas de doute, examinez la mise en œuvre de cet observable. Si l'observable a écrit une logique de nettoyage dans son
unsubscribe()
, qui est généralement la fonction renvoyée par le constructeur, alors vous avez de bonnes raisons d'envisager sérieusement d'appelerunsubscribe()
.la source
La documentation officielle d'Angular 2 fournit une explication pour savoir quand se désinscrire et quand elle peut être ignorée en toute sécurité. Jetez un œil à ce lien:
https://angular.io/docs/ts/latest/cookbook/component-communication.html#!#bidirectional-service
Recherchez le paragraphe avec le titre Parent et enfants communiquent via un service , puis la case bleue:
J'espère que ceci vous aide.
la source
Basé sur: Utilisation de l'héritage de classe pour se connecter au cycle de vie du composant Angular 2
Une autre approche générique:
Et utilise :
la source
this.componentDestroyed$.next()
La réponse officielle (et les variantes) de l'édition n ° 3 fonctionne bien, mais ce qui m'attire, c'est le brouillage de la logique métier autour de l'abonnement observable.
Voici une autre approche utilisant des wrappers.
Le fichier subscribeAndGuard.ts est utilisé pour créer une nouvelle extension observable à encapsuler
.subscribe()
et en son sein à encapsulerngOnDestroy()
.L'utilisation est la même que
.subscribe()
, sauf pour un premier paramètre supplémentaire référençant le composant.Voici un composant avec deux abonnements, un avec le wrapper et un sans. La seule mise en garde est qu'il doit implémenter OnDestroy (avec un corps vide si vous le souhaitez), sinon Angular ne sait pas appeler la version encapsulée.
Un plongeur de démonstration est ici
Une note supplémentaire: Re Edit 3 - La solution «officielle», cela peut être simplifié en utilisant takeWhile () au lieu de takeUntil () avant les abonnements, et un simple booléen plutôt qu'un autre observable dans ngOnDestroy.
la source
Étant donné que la solution de seangwright (Édition 3) semble être très utile, j'ai également trouvé difficile d'incorporer cette fonctionnalité dans le composant de base, et je suggère aux autres coéquipiers du projet de se rappeler d'appeler super () sur ngOnDestroy pour activer cette fonctionnalité.
Cette réponse fournit un moyen de se libérer du super appel et de faire de "componentDestroyed $" un noyau du composant de base.
Et puis vous pouvez utiliser cette fonctionnalité librement par exemple:
la source
Suite à la réponse de @seangwright , j'ai écrit une classe abstraite qui gère les abonnements aux observables "infinis" dans les composants:
Pour l'utiliser, il suffit de l'étendre dans votre composant angulaire et d'appeler la
subscribe()
méthode comme suit:Il accepte également l'erreur et complète les rappels comme d'habitude, un objet observateur, ou pas les rappels du tout. N'oubliez pas d'appeler
super.ngOnDestroy()
si vous implémentez également cette méthode dans le composant enfant.Trouvez ici une référence supplémentaire de Ben Lesh: RxJS: Don't Unsubscribe .
la source
J'ai essayé la solution de seangwright (Edit 3)
Cela ne fonctionne pas pour Observable créé par minuterie ou intervalle.
Cependant, je l'ai fait fonctionner en utilisant une autre approche:
la source
J'aime les deux dernières réponses, mais j'ai rencontré un problème si la sous-classe référencée
"this"
dansngOnDestroy
.Je l'ai modifié pour être ceci, et il semble qu'il ait résolu ce problème.
la source
this.ngOnDestroy = () => { f.bind(this)(); this.componentDestroyed$.complete(); };
Dans le cas où la désinscription est nécessaire, l'opérateur suivant pour la méthode de tuyau observable peut être utilisé
il peut être utilisé comme ceci:
L'opérateur encapsule la méthode ngOnDestroy du composant.
Important: l'opérateur doit être le dernier dans un tuyau observable.
la source
Vous devez généralement vous désinscrire lorsque les composants sont détruits, mais Angular va le gérer de plus en plus au fur et à mesure, par exemple dans la nouvelle version mineure d'Angular4, ils ont cette section pour acheminer le désabonnement:
De plus, l'exemple ci-dessous est un bon exemple d'Angular pour créer un composant et le détruire après, regardez comment le composant implémente OnDestroy, si vous avez besoin de onInit, vous pouvez également l'implémenter dans votre composant, comme implémente
OnInit, OnDestroy
la source
Un autre petit ajout aux situations mentionnées ci-dessus est:
la source
dans l'application SPA à la fonction ngOnDestroy (cycle de vie angulaire) Pour chaque abonnement, vous devez vous désinscrire . avantage => pour éviter que l'état ne devienne trop lourd.
par exemple: dans le composant1:
en service:
dans le composant 2:
la source
Pour gérer l'abonnement, j'utilise une classe "Unsubscriber".
Voici la classe de désabonnement.
Et vous pouvez utiliser cette classe dans n'importe quel composant / service / effet, etc.
Exemple:
la source
Vous pouvez utiliser la dernière
Subscription
classe pour vous désinscrire de l'Observable avec un code pas si compliqué.Nous pouvons le faire avec,
normal variable
mais ce seraoverride the last subscription
à chaque nouvel abonnement, alors évitez cela, et cette approche est très utile lorsque vous traitez avec plus de nombre d'Observables et de type d'Observables commeBehavoiurSubject
etSubject
Abonnement
vous pouvez l'utiliser de deux manières,
vous pouvez directement pousser l'abonnement à Subscription Array
utilisation
add()
deSubscription
A
Subscription
peut détenir des abonnements enfants et les désinscrire en toute sécurité. Cette méthode gère les erreurs possibles (par exemple si des abonnements enfants sont nuls).J'espère que cela t'aides.. :)
la source
Le package SubSink, une solution simple et cohérente de désinscription
Comme personne d'autre ne l'a mentionné, je veux recommander le package Subsink créé par Ward Bell: https://github.com/wardbell/subsink#readme .
Je l'ai utilisé sur un projet où nous sommes plusieurs développeurs qui l'utilisent tous. Cela aide beaucoup d'avoir une méthode cohérente qui fonctionne dans toutes les situations.
la source
Pour les observables qui se terminent directement après avoir émis le résultat comme
AsyncSubject
ou par exemple les observables des requêtes http et ainsi vous n'avez pas besoin de vous désinscrire. Cela ne fait pas de mal de les appelerunsubscribe()
, mais si l'observable estclosed
la méthode de désabonnement ne fera tout simplement rien :Lorsque vous avez des observables à longue durée de vie qui émettent plusieurs valeurs dans le temps (comme par exemple a
BehaviorSubject
ou aReplaySubject
), vous devez vous désabonner pour éviter les fuites de mémoire.Vous pouvez facilement créer un observable qui se termine directement après avoir émis un résultat à partir de ces observables à longue durée de vie à l'aide d'un opérateur de tuyau. Dans certaines réponses, le
take(1)
tuyau est mentionné. Mais je préfère lafirst()
pipe . La différencetake(1)
est qu'elle:Un autre avantage du premier canal est que vous pouvez passer un prédicat qui vous aidera à renvoyer la première valeur qui satisfait certains critères:
First se terminera directement après avoir émis la première valeur (ou lorsque vous passez un argument de fonction la première valeur qui satisfait votre prédicat), il n'est donc pas nécessaire de vous désinscrire.
Parfois, vous ne savez pas si vous avez ou non une longue durée de vie observable. Je ne dis pas que c'est une bonne pratique, mais vous pouvez alors toujours ajouter le
first
canal juste pour vous assurer que vous n'aurez pas besoin de vous désabonner manuellement. L'ajout d'unfirst
tuyau supplémentaire sur un observable qui n'émettra qu'une seule valeur ne fait pas de mal.Pendant le développement, vous pouvez utiliser le
single
canal qui échouera si la source observable émet plusieurs événements. Cela peut vous aider à explorer le type d'observable et s'il est nécessaire de vous désinscrire ou non.Les
first
etsingle
semblent très similaires, les deux canaux peuvent prendre un prédicat facultatif mais les différences sont importantes et bien résumées dans cette réponse de stackoverflow ici :Remarque J'ai essayé d'être aussi précis et complet que possible dans ma réponse en faisant référence à la documentation officielle, mais veuillez commenter s'il manque quelque chose d'important ...
la source
--- Mettre à jour la solution Angular 9 et Rxjs 6
unsubscribe
au cours dungDestroy
cycle de vie du composant angulairetakeUntil
dans RxjsngOnInit
cela ne se produit qu'une seule fois lorsque le composant init.Nous avons également des
async
tuyaux. Mais, celui-ci utilise sur le modèle (pas dans le composant Angular).la source