📜  Angular RxJs 我什么时候应该取消订阅“订阅”-TypeScript (1)

📅  最后修改于: 2023-12-03 14:39:13.467000             🧑  作者: Mango

Angular RxJs: 我什么时候应该取消订阅?

简介

RxJs 是 Angular 中的一个重要的库,它是响应式编程的中心。RxJs 通过“可观察对象”来管理异步数据流。但是我们必须时常小心,避免造成内存泄漏。

什么是“订阅”?

在 RxJs 中,我们通过“订阅”一个可观察对象来接收它所发出的“通知”。可观察对象通常是异步的,比如AJAX请求,定时器或鼠标事件等。

我们通常使用“subscribe”方法来订阅一个可观察对象。当然,在代码的生命周期结束时,我们需要手动取消订阅。

为什么需要取消订阅?

当你订阅一个可观察对象,RxJs 就会创建一个内部数据结构,其中存储了订阅的信息。如果我们不手动取消订阅,这些数据将会一直保存在内存中,直到应用关闭。

这就是内存泄漏的起因。

什么时候取消订阅?

如何确定应该在何时取消订阅?这通常取决于场景。以下是一些你应该取消订阅的情况:

  1. 组件销毁时

通常,我们在组件中订阅可观察对象,这意味着当组件销毁时,订阅也将自动取消。你可以在组件中实现 ngOnDestroy 钩子函数。

import { Component, OnInit, OnDestroy } from '@angular/core';
import { Observable, Subscription } from 'rxjs';

@Component({
  selector: 'app-my-component',
  templateUrl: './my-component.component.html',
  styleUrls: ['./my-component.component.scss']
})
export class MyComponentComponent implements OnDestroy {
  private subscription: Subscription;

  constructor() {
    const source = new Observable(observer => {
      observer.next('Hello');
      observer.next('World');
    });

    this.subscription = source.subscribe(val => console.log(val));
  }

  ngOnDestroy() {
    this.subscription.unsubscribe(); // 取消订阅
  }
}
  1. 只需要订阅一次

如果你只需要订阅一次,你可以使用 take 操作符。take 在接收到指定数量的数据(或者在时间间隔过去之后)后,会自动完成并取消订阅。

import { Component, OnInit } from '@angular/core';
import { Observable } from 'rxjs';
import { take } from 'rxjs/operators';

@Component({
  selector: 'app-my-component',
  templateUrl: './my-component.component.html',
  styleUrls: ['./my-component.component.scss']
})
export class MyComponentComponent implements OnInit {
  constructor() {}

  ngOnInit() {
    const source = new Observable(observer => {
      observer.next('Hello');
      observer.next('World');
      observer.complete();
    });

    source.pipe(take(1)).subscribe(val => console.log(val)); // 只订阅一次
  }
}
  1. 取得单一结果

如果你希望取得一个单一结果,你可以使用 first 操作符。first 在接收到第一条数据后会自动完成并取消订阅。

import { Component, OnInit } from '@angular/core';
import { Observable } from 'rxjs';
import { first } from 'rxjs/operators';

@Component({
  selector: 'app-my-component',
  templateUrl: './my-component.component.html',
  styleUrls: ['./my-component.component.scss']
})
export class MyComponentComponent implements OnInit {
  constructor() {}

  ngOnInit() {
    const source = new Observable(observer => {
      observer.next('Hello');
      observer.next('World');
      observer.complete();
    });

    source.pipe(first()).subscribe(val => console.log(val)); // 取得第一条数据
  }
}
结论

RxJs 是 Angular 最重要的库之一。订阅是一个核心概念,你需要时刻小心避免内存泄漏。无论何时与 RxJs 打交道,你都应该牢记必须手动取消订阅。

参考资料

RxJs 官方文档