web-dev-qa-db-fra.com

Subject.complete () désinscrit-il tous les auditeurs?

Je crée un service de dialogue de confirmation simple (Angular 2) avec cette méthode:

confirm(body?: string, title?: string): Subject<void> {
    this.confirmation = new Subject<void>();
    // ... show dialog here... "are you sure?"
    return this.confirmation;
}

_onYesClicked() {
  // ... closing the dialog
  this.confirmation.next();
  this.confirmation.complete();
} 

_onNoClicked() {
  // ... closing the dialog
  this.confirmation.complete();
}

Usage:

confirmationService.confirm().subscribe(() => alert("CONFIRMED"));

Si quelqu'un utilise le service, il obtient un sujet (qui est un observable) retourné et peut "s'abonner ()". L'abonnement est appelé lorsque "oui" est cliqué et donc la confirmation a été donnée ...

Est-ce la bonne façon de procéder? Et plus important encore ... l'appel à

this.confirmation.complete();

désinscrire les auditeurs abonnés et donc éviter toute référence persistante (fuite de mémoire)?

25
Wolfgang

Si vous voulez être sûr qu'il supprime tous les observateurs, vous pouvez le vérifier par vous-même dans https://github.com/ReactiveX/rxjs/blob/master/src/internal/Subject.ts#L91 . Il appelle complete() sur tous les observateurs (les observateurs ne sont généralement que des objets stupides implémentant interface d'observateur ) puis définit this.observers.length = 0;. Donc, la réponse est oui.

Votre approche est valide, c'est fondamentalement la même chose qu'Angular2 fait régulièrement avec EventEmitter. Une seule chose que vous pouvez améliorer est de commencer à utiliser asObservable() lors de l'exposition de Subjects. Cela masquera le fait que vous utilisez un Subject en dessous et renverra juste un observable normal. De cette façon, vous ne laissez pas vos utilisateurs par accident (ou par malentendu) essayer d'appeler next(), complete() ou error() sur votre Subject.

En ce qui concerne les fuites de mémoire, cela doit être géré par RxJS, donc vous ne devriez pas vous en soucier et s'il y a un problème, les auteurs le remarqueraient probablement avant vous.

Jetez également un œil à ceci: Observable vs Subject et asObservable

31
martin