Home > Article > Web Front-end > A brief discussion on unsubscribing in Angular
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(); } }
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() { // 手动执行取消订阅的操作 } }
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(); } }Infinite Observables
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(); } }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(); } }
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('todos'); } }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: 'async', pure: false}) export class AsyncPipe implements OnDestroy, PipeTransform { // ... constructor(private _ref: ChangeDetectorRef) {} ngOnDestroy(): void { if (this._subscription) { this._dispose(); } } }@HostListener
export class TestDirective { @HostListener('click') onClick() { .... } }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('document', "click", event =>{...}); // unsubscribe this.handler();
Finite Observable
export class TestComponent { constructor(private http: Http) { } ngOnInit() { // 表示1s后发出值,然后就结束了 Observable.timer(1000).subscribe(console.log); this.http.get('http://api.com').subscribe(console.log); } }timer operatorOperator signature
Copy code The code is as follows:
public static timer(initialDelay: number | Date, period: number, scheduler: Scheduler): Observable
// 每隔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));Final suggestion
export class TestComponent { constructor(private store: Store) { } private componetDestroyed: Subject = new Subject(); todos: Subscription; posts: Subscription; ngOnInit() { this.todos = this.store.select('todos') .takeUntil(this.componetDestroyed).subscribe(console.log); this.posts = this.store.select('posts') .takeUntil(this.componetDestroyed).subscribe(console.log); } ngOnDestroy() { this.componetDestroyed.next(); this.componetDestroyed.unsubscribe(); } }takeUntil operatorOperator signature
public takeUntil(notifier: Observable): Observable<T>Operator function
var interval = Rx.Observable.interval(1000); var clicks = Rx.Observable.fromEvent(document, 'click'); var result = interval.takeUntil(clicks); result.subscribe(x => console.log(x));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!