简介
Angel处理从可观察订阅的取消订阅,如从HTTp服务返回的订阅或在使用Async pipe.]时然而,对于其他情况,管理所有订阅并确保取消订阅长期订阅可能很快就会变得困难。取消订阅大多数订阅的政策也会有其自身的问题。
在本文中,您将看到一个依赖于手动订阅和取消订阅的示例角度应用程序。然后,您将把它与一个示例的角度应用程序进行比较,该应用程序使用takUntil
操作符来声明性地管理订阅。
前提条件
如果您想继续阅读本文,您将需要:
- 熟悉RxJS library,,特别是
可观察
和订阅
会更好。 - 熟悉阿波罗和GraphQL将有所帮助,但不是必需的。
本教程已通过Node v15.3.0、npm
v6.14.9、@angular/core
v11.0.4、rxjs
v6.6.3、apollo-angular
v2.1.0、graph-tag
v2.11.0验证。本文经过编辑,以反映从较早版本的@Angel/core
和rxjs
迁移的变化。
手动退订
让我们从一个例子开始,你将手动取消订阅两个订阅。
在本例中,代码订阅了ApollowatchQuery
以从GraphQL端点获取数据。
该代码还创建了一个间隔可观察值,当onStartInterval
方法被调用时,您可以订阅它。
1import { Component, OnInit, OnDestroy } from '@angular/core';
2
3import { Subscription, interval } from 'rxjs';
4
5import { Apollo } from 'apollo-angular';
6import gql from 'graphql-tag';
7
8@Component({ ... })
9export class AppComponent implements OnInit, OnDestroy {
10 myQuerySubscription: Subscription;
11 myIntervalSubscription: Subscription;
12
13 constructor(private apollo: Apollo) {}
14
15 ngOnInit() {
16 this.myQuerySubscription = this.apollo.watchQuery<any>({
17 query: gql`
18 query getAllPosts {
19 allPosts {
20 title
21 description
22 publishedAt
23 }
24 }
25 `
26 })
27 .valueChanges
28 .subscribe(({data}) => {
29 console.log(data);
30 });
31 }
32
33 onStartInterval() {
34 this.myIntervalSubscription = interval(250).subscribe(value => {
35 console.log('Current value:', value);
36 });
37 }
38
39 ngOnDestroy() {
40 this.myQuerySubscription.unsubscribe();
41
42 if (this.myIntervalSubscription) {
43 this.myIntervalSubscription.unsubscribe();
44 }
45 }
46}
现在想象一下,您的组件有许多类似的订阅,当组件被销毁时,它可能很快成为一个相当大的过程,以确保所有内容都被取消订阅。
使用takUntil
声明退订
解决方案是使用takeUntil
操作符组合订阅,并使用在ngOnDestroy
生命周期钩子中发出truthy值的主题。
下面的代码片段做了完全相同的事情,但这一次代码将以声明方式取消订阅。您会注意到一个额外的好处是您不再需要保留对我们订阅的引用。
1import { Component, OnInit, OnDestroy } from '@angular/core';
2
3import { Subject, interval } from 'rxjs';
4import { takeUntil } from 'rxjs/operators';
5
6import { Apollo } from 'apollo-angular';
7import gql from 'graphql-tag';
8
9@Component({ ... })
10export class AppComponent implements OnInit, OnDestroy {
11 destroy$: Subject<boolean> = new Subject<boolean>();
12
13 constructor(private apollo: Apollo) {}
14
15 ngOnInit() {
16 this.apollo.watchQuery<any>({
17 query: gql`
18 query getAllPosts {
19 allPosts {
20 title
21 description
22 publishedAt
23 }
24 }
25 `
26 })
27 .valueChanges
28 .pipe(takeUntil(this.destroy$))
29 .subscribe(({data}) => {
30 console.log(data);
31 });
32 }
33
34 onStartInterval() {
35 interval(250)
36 .pipe(takeUntil(this.destroy$))
37 .subscribe(value => {
38 console.log('Current value:', value);
39 });
40 }
41
42 ngOnDestroy() {
43 this.destroy$.next(true);
44 this.destroy$.unsubscribe();
45 }
46}
请注意,使用像takUntil
这样的操作符而不是手动取消订阅也会完成可观察对象,触发对可观察对象的任何完成事件。
请务必检查您的代码,以确保这不会产生任何意外的副作用。
结论
在本文中,您了解了如何使用takUntil
进行声明性退订。取消订阅不必要的订阅有助于防止内存泄漏。声明式取消订阅允许您不需要对订阅的引用。
还有其他类似的RxJS操作符-如take
,takeWhile
和first
-它们都将完成观察对象。
如果您想了解更多有关ANGLE的信息,请查看我们的ANGLE主题页面以获取练习和编程项目。