Maison  >  Article  >  interface Web  >  Explication détaillée du moment où annuler l'abonnement dans Angular

Explication détaillée du moment où annuler l'abonnement dans Angular

小云云
小云云original
2017-12-12 11:05:291579parcourir

Vous savez peut-être que lorsque vous vous abonnez à un objet observable ou configurez un écouteur d'événements, à un moment donné, vous devez effectuer une opération de désabonnement pour libérer la mémoire du système d'exploitation. Sinon, votre application pourrait souffrir de fuites de mémoire.

Examinons ensuite quelques scénarios courants dans lesquels les opérations de désabonnement doivent être effectuées manuellement dans le hook de cycle de vie ngOnDestroy. Cet article présente principalement une brève discussion sur le moment où annuler un abonnement dans Angular. L'éditeur pense que c'est plutôt bien. Maintenant, je vais le partager avec vous et vous donner une référence. Suivons l'éditeur et jetons un œil. J'espère que cela pourra aider tout le monde.

Scénario de ressources de publication manuelle

Formulaire


export class TestComponent {

 ngOnInit() {
  this.form = new FormGroup({...});
  // 监听表单值的变化
  this.valueChanges = this.form.valueChanges.subscribe(console.log);
  // 监听表单状态的变化              
  this.statusChanges = this.form.statusChanges.subscribe(console.log);
 }

 ngOnDestroy() {
  this.valueChanges.unsubscribe();
  this.statusChanges.unsubscribe();
 }
}


La solution ci-dessus est également applicable à d'autres contrôles de formulaire.

Itinéraire


export class TestComponent {
 constructor(private route: ActivatedRoute, private router: Router) { }

 ngOnInit() {
  this.route.params.subscribe(console.log);
  this.route.queryParams.subscribe(console.log);
  this.route.fragment.subscribe(console.log);
  this.route.data.subscribe(console.log);
  this.route.url.subscribe(console.log);
  
  this.router.events.subscribe(console.log);
 }

 ngOnDestroy() {
  // 手动执行取消订阅的操作
 }
}


Service de rendu


export class TestComponent {
 constructor(
  private renderer: Renderer2, 
  private element : ElementRef) { }

 ngOnInit() {
  this.click = this.renderer
    .listen(this.element.nativeElement, "click", handler);
 }

 ngOnDestroy() {
  this.click.unsubscribe();
 }
}


Observables infinis

Lorsque vous utilisez l'opérateur interval() ou fromEvent(), vous créez un objet observable infini. Dans ce cas, lorsque nous n’avons plus besoin de les utiliser, nous devons nous désabonner et libérer les ressources manuellement.


export class TestComponent {
 constructor(private element : ElementRef) { }

 interval: Subscription;
 click: Subscription;

 ngOnInit() {
  this.interval = Observable.interval(1000).subscribe(console.log);
  this.click = Observable.fromEvent(this.element.nativeElement, 'click')
              .subscribe(console.log);
 }

 ngOnDestroy() {
  this.interval.unsubscribe();
  this.click.unsubscribe();
 }
}


Boutique Redux


export class TestComponent {

 constructor(private store: Store) { }

 todos: Subscription;

 ngOnInit() {
   /**
   * select(key : string) {
   *  return this.map(state => state[key]).distinctUntilChanged();
   * }
   */
   this.todos = this.store.select('todos').subscribe(console.log); 
 }

 ngOnDestroy() {
  this.todos.unsubscribe();
 }
}


Pas besoin de libérer manuellement les scénarios de ressources

AsyncPipe


@Component({
 selector: 'test',
 template: `<todos [todos]="todos$ | async"></todos>`
})
export class TestComponent {
 constructor(private store: Store) { }
 
 ngOnInit() {
   this.todos$ = this.store.select(&#39;todos&#39;);
 }
}


Lorsque le composant est détruit, le pipeline asynchrone effectuera automatiquement l'opération de désabonnement, évitant ainsi les risques de fuites de mémoire.

Extrait de code source angulaire d'AsyncPipe


@Pipe({name: &#39;async&#39;, pure: false})
export class AsyncPipe implements OnDestroy, PipeTransform {
 // ...
 constructor(private _ref: ChangeDetectorRef) {}

 ngOnDestroy(): void {
  if (this._subscription) {
   this._dispose();
  }
 }
}


@HostListener


export class TestDirective {
 @HostListener(&#39;click&#39;)
 onClick() {
  ....
 }
}


Il est à noter que si vous utilisez le décorateur @HostListener, nous ne pouvons pas vous désinscrire manuellement lors de l'ajout d'écouteurs d'événements. Si vous devez supprimer manuellement la surveillance des événements, vous pouvez utiliser la méthode suivante :


// subscribe
this.handler = this.renderer.listen(&#39;document&#39;, "click", event =>{...});

// unsubscribe
this.handler();


Finite Observable

Lorsque vous utilisez des services HTTP ou des objets observables timer, vous n'avez pas besoin de vous désinscrire manuellement.


export class TestComponent {
 constructor(private http: Http) { }

 ngOnInit() {
  // 表示1s后发出值,然后就结束了
  Observable.timer(1000).subscribe(console.log);
  this.http.get(&#39;http://api.com&#39;).subscribe(console.log);
 }
}


opérateur de minuterie

Signature de l'opérateur


Copier le code Le code est le suivant :


minuterie statique publique (initialDelay : numéro | Date, période : numéro, planificateur : Planificateur) : Observable


Fonction opérateur

timer renvoie un observable qui émet une séquence infinie d'auto-augmentation avec un certain intervalle de temps. Cet intervalle est choisi par. toi. .

Exemples d'opérateurs


// 每隔1秒发出自增的数字,3秒后开始发送
var numbers = Rx.Observable.timer(3000, 1000);
numbers.subscribe(x => console.log(x));

// 5秒后发出一个数字
var numbers = Rx.Observable.timer(5000);
numbers.subscribe(x => console.log(x));


Conseil final

Vous devrait appeler la méthode unsubscribe() le moins possible. Vous pouvez en savoir plus sur le sujet dans l'article RxJS : Ne pas vous désabonner.

Des exemples spécifiques sont les suivants :


export class TestComponent {
 constructor(private store: Store) { }

 private componetDestroyed: Subject = new Subject();
 todos: Subscription;
 posts: Subscription;

 ngOnInit() {
   this.todos = this.store.select(&#39;todos&#39;)
           .takeUntil(this.componetDestroyed).subscribe(console.log); 
           
   this.posts = this.store.select(&#39;posts&#39;)
           .takeUntil(this.componetDestroyed).subscribe(console.log); 
 }

 ngOnDestroy() {
  this.componetDestroyed.next();
  this.componetDestroyed.unsubscribe();
 }
}


opérateur takeUntil

Signature de l'opérateur


public takeUntil(notifier: Observable): Observable<T>


Effet opérateur

Émet la valeur émise par la source Observable jusqu'à ce que le notifier Observable émet des valeurs.

Exemple d'opérateur


var interval = Rx.Observable.interval(1000);
var clicks = Rx.Observable.fromEvent(document, &#39;click&#39;);
var result = interval.takeUntil(clicks);

result.subscribe(x => console.log(x));


Recommandations associées :

Explication détaillée de la validation du formulaire dans AngularJS

Explication détaillée de l'utilisation des instructions personnalisées dans AngularJS_AngularJS

Explication détaillée du filtrage personnalisé dans AngularJS Device_AngularJS

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn