Home > Web Front-end > JS Tutorial > body text

A brief discussion on unsubscribing in Angular

小云云
Release: 2018-01-16 09:02:49
Original
1540 people have browsed it

This article mainly introduces a brief discussion on when to cancel a subscription in Angular. The editor thinks it is quite good, so I will share it with you now and give it as a reference. Let’s follow the editor to take a look, I hope it can help everyone.

You may know that when you subscribe to an Observable object or set up an event listener, at some point in time, you need to perform an unsubscription operation to release the operating system's memory. Otherwise, your application may suffer from memory leaks.

Next let's take a look at some common scenarios where unsubscription operations need to be performed manually in the ngOnDestroy life cycle hook.

Manual release resource scenario

Form


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();
 }
}
Copy after login

The above scheme also applies to Other form controls.

Routing


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() {
  // 手动执行取消订阅的操作
 }
}
Copy after login

Renderer Service


##

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();
 }
}
Copy after login

Infinite Observables


When you use the interval() or fromEvent() operator, you create an infinite Observable object. In this case, when we no longer need to use them, we need to unsubscribe and release the resources manually.


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();
 }
}
Copy after login

Redux Store



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();
 }
}
Copy after login

No need to manually release resource scenarios

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;);
 }
}
Copy after login

When the component is destroyed, the async pipeline will automatically perform the unsubscription operation to avoid memory Risk of leakage.

Angular AsyncPipe source code snippet


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

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

@HostListener



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

Things to note Yes, if you use the @HostListener decorator, we cannot manually unsubscribe when adding event listeners. If you need to manually remove event monitoring, you can use the following method:


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

// unsubscribe
this.handler();
Copy after login

Finite Observable

When you You also don't need to manually unsubscribe when using an HTTP service or timer Observable object.


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);
 }
}
Copy after login

timer operator

Operator signature


Copy code The code is as follows:

public static timer(initialDelay: number | Date, period: number, scheduler: Scheduler): Observable

Operator function


timer return An Observable that emits an infinite incrementing sequence with a certain time interval, which is chosen by you.

Operator examples



// 每隔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));
Copy after login

Final suggestion


You should call the unsubscribe() method as little as possible , you can learn more about Subject in this article RxJS: Don't Unsubscribe.

Specific examples are as follows:


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();
 }
}
Copy after login

takeUntil operator

Operator signature



public takeUntil(notifier: Observable): Observable<T>
Copy after login

Operator function


Emits the value emitted by the source Observable until the notifier Observable emits the value.

Operator examples



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));
Copy after login
Related recommendations:


node.js publish-subscribe mode Method

Detailed explanation of JavaScript publish-subscribe mode usage

PHP WeChat public platform development Subscription event processing_PHP tutorial

The above is the detailed content of A brief discussion on unsubscribing in Angular. For more information, please follow other related articles on the PHP Chinese website!

Related labels:
source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
About us Disclaimer Sitemap
php.cn:Public welfare online PHP training,Help PHP learners grow quickly!