项目

管理 RxJS 订阅

SubscriptionService 是一个实用工具服务,用于在 Angular 组件和指令中轻松取消订阅 RxJS 可观察对象。请参阅为什么应在实例销毁时取消订阅可观察对象

开始使用

必须在组件或指令级别提供 SubscriptionService,因为它未在根级别提供,并且需要与组件/指令生命周期同步工作。之后才能注入并开始使用它。

import { SubscriptionService } from '@abp/ng.core';
import { inject } from '@angular/core';

@Component({
  /* 类元数据 */
  providers: [SubscriptionService],
})
class DemoComponent {
  count$ = interval(1000);

  private subscription = inject(SubscriptionService);

  constructor() {
    this.subscription.addOne(this.count$, console.log);
  }
}

count$ 发出的值将在组件销毁前持续记录。您无需手动取消订阅。

请不要尝试使用单例 SubscriptionService。它根本无法工作。

使用方式

如何订阅可观察对象

您可以传递一个 next 函数和一个 error 函数。

@Component({
  /* 类元数据 */
  providers: [SubscriptionService],
})
class DemoComponent implements OnInit {
  private subscription = inject(SubscriptionService);

  ngOnInit() {
    const source$ = interval(1000);
    const nextFn = value => console.log(value * 2);
    const errorFn = error => {
      console.error(error);
      return of(null);
    };

    this.subscription.addOne(source$, nextFn, errorFn);
  }
}

或者,您可以传递一个观察者对象。

@Component({
  /* 类元数据 */
  providers: [SubscriptionService],
})
class DemoComponent implements OnInit {
  private subscription = inject(SubscriptionService);

  ngOnInit() {
    const source$ = interval(1000);
    const observer = {
      next: value => console.log(value * 2),
      complete: () => console.log('完成'),
    };

    this.subscription.addOne(source$, observer);
  }
}

addOne 方法返回单个订阅,以便您后续使用。详情请参阅以下主题。

如何在实例销毁前取消订阅

有两种方法可以实现。如果您不打算再次订阅,可以使用 closeAll 方法。

@Component({
  /* 类元数据 */
  providers: [SubscriptionService],
})
class DemoComponent implements OnInit {
  private subscription = inject(SubscriptionService);

  ngOnInit() {
    this.subscription.addOne(interval(1000), console.log);
  }

  onSomeEvent() {
    this.subscription.closeAll();
  }
}

这将清除所有订阅,但您将无法再次订阅。如果您计划添加另一个订阅,可以改用 reset 方法。

@Component({
  /* 类元数据 */
  providers: [SubscriptionService],
})
class DemoComponent implements OnInit {
  private subscription = inject(SubscriptionService);

  ngOnInit() {
    this.subscription.addOne(interval(1000), console.log);
  }

  onSomeEvent() {
    this.subscription.reset();
    this.subscription.addOne(interval(1000), console.warn);
  }
}

如何取消单个订阅

有时,您可能需要取消特定订阅,但保留其他订阅。在这种情况下,可以使用 closeOne 方法。

@Component({
  /* 类元数据 */
  providers: [SubscriptionService],
})
class DemoComponent implements OnInit {
  countSubscription: Subscription;
  private subscription = inject(SubscriptionService);

  ngOnInit() {
    this.countSubscription = this.subscription.addOne(
      interval(1000),
      console.log
    );
  }

  onSomeEvent() {
    this.subscription.closeOne(this.countSubscription);
    console.log(this.countSubscription.closed); // true
  }
}

如何从跟踪的订阅中移除单个订阅

您可能希望控制特定订阅。在这种情况下,可以使用 removeOne 方法将其从跟踪的订阅中移除。

@Component({
  /* 类元数据 */
  providers: [SubscriptionService],
})
class DemoComponent implements OnInit {
  countSubscription: Subscription;
  private subscription = inject(SubscriptionService);

  ngOnInit() {
    this.countSubscription = this.subscription.addOne(
      interval(1000),
      console.log
    );
  }

  onSomeEvent() {
    this.subscription.removeOne(this.countSubscription);
    console.log(this.countSubscription.closed); // false
  }
}

如何检查是否已取消所有订阅

请使用 isClosed 获取器检查之前是否调用了 closeAll

@Component({
  /* 类元数据 */
  providers: [SubscriptionService],
})
class DemoComponent implements OnInit {
  private subscription = inject(SubscriptionService);

  ngOnInit() {
    this.subscription.addOne(interval(1000), console.log);
  }

  onSomeEvent() {
    console.log(this.subscription.isClosed); // false
  }
}
在本文档中