Angular 5中的rxjs永久订阅 [英] Persistent subscriptions with rxjs in Angular 5

查看:68
本文介绍了Angular 5中的rxjs永久订阅的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对Angular 5中的rxjs还是有点陌生​​,很难提出我的问题.我仍然希望有一些提示.

I'm still a bit new to rxjs in Angular 5 and it a bit hard to formulate my question. Still I hope for some tips.

我经常会得到相同的设置:

I often end up with the same setup:

  • 多个组件可显示相同的数据
  • 访问数据的单一服务

现在,当通过Observables接收数据时,我有2个选择:

Now I have 2 options when receiving data via Observables:

a)订阅一个可观察对象以获取一次数据,然后再次订阅以获取更新

a) Subscribe to an observable to get data once, and subscribe again to get updates

b)订阅可观察的数据,并在数据更改时始终获取更新

b) Subscribe to an observable and always get updates when data changes

a)直截了当,但是b)我经常遇到麻烦,想知道这是否是使用Observables的正确方法.

a) ist straight forward, but with b) I often have troubles and wondering if this is the right way to use Observables.

一个问题是,取消订阅在某些情况下变得很重要,而缺少取消订阅会导致每次可观察对象的更新都会执行严重的垃圾操作.

One issue is, that unsubscribe gets important in some cases, and missing the unsubscribe leads to serious garbage being executed with each update of the observable.

另一方面,对于选项a),当另一个组件正在更新基础数据时,我可能会错过一个组件中的某些更新.

On the other hand, with option a) I might miss some updates in one component when another component is updating the underlying data.

是否有最佳实践来避免所有这些陷阱?

Is there any best practice to avoid all these pitfalls?

推荐答案

听起来像您要弄清楚的概念是使用Angular时如何规范RxJS的订阅管理.为此,我想到了三个主要选项:

It sounds like the concept you are trying to figure out is how to regulate subscription management for RxJS when using Angular. There are three main options that come to mind for this:

  1. 使用 async 管道自动创建和删除订阅.如果要严格根据可观察对象发出的数据进行UI更改,则 async 管道会在创建组件时方便地创建给定可观察对象的预订,并在销毁组件时删除这些预订.可以说这是使用订阅的最干净的方法.
  1. Automatically create and delete subscriptions using the async pipe. If you want to make UI changes based strictly on data emitted from an observable, then the async pipe handily creates a subscription to the given observable when the component is created and removes those subscription when the component is destroyed. This is arguably the cleanest way to use subscriptions.

例如:

@Component({
    selector: 'my-component',
    template: `
        <div *ngFor="let value of value$ | async">
            {{value}}
        </div>
    `
})
export class MyComponent {
    public value$: Observable<String> = this.myValueService
        .getValues()
        .map(value => `Value: $value`);
    constructor(myValueService: MyValueService) {}
}

    通过在 ngOnInit 方法中创建类级别的 Subscription 对象,然后在 ngOnDestroy 方法中取消订阅,来管理组件中的订阅.这是我需要访问组件代码中的订阅时遵循的约定.在每个使用订阅的组件中都有 ngOnInit ngOnDestroy 方法会增加样板,但是如果您需要在组件代码中进行订阅,通常这是必需的.
  1. Manage subscriptions in components by creating class-level Subscription objects in the ngOnInit method and then unsubscribing in the ngOnDestroy method. This is the convention that I tend toward when I need access to the subscriptions within the component code. Having ngOnInit and ngOnDestroy methods in every component that uses subscriptions adds boilerplate but is generally necessary if you need subscriptions in your component code.

例如:

@Component({
    selector: 'my-component',
    template: `
        <div #myDiv></div>
    `
})
export class MyComponent implements OnInit, OnDestroy {
    private mySub: Subscription;
    constructor(myValueService: MyValueService) {}

    public ngOnInit() {
        this.mySub = this.myValueService.getValue().subscribe((value) => {
            console.log(value);
            // Do something with value
        });
    }
    public ngOnDestroy() {
        this.mySub.unsubscribe();
    }
}

  1. 通过使用限制操作(例如 first())来限制订阅期限.当您启动对 HttpClient observables的订阅时,默认情况下会执行此操作.这样做的好处是只需要很少的代码,但是也可能导致未清除订阅的情况(例如,如果观察对象永不发出).
  1. Limit subscription life by using a limiting operation, such as first(). This is what is done by default when you initiate a subscription to HttpClient observables. This has the benefit of requiring little code, but it can also lead to cases where the subscription is not cleaned up (e.g., if the observable never emits).

如果我想对可观察对象进行的所有操作都可以在视图中完成,那么我实际上总是使用选项1 .根据我的经验,这涵盖了大多数情况.您始终可以使用中间可观测对象来生成一个可观测对象,如果需要,可以在视图中进行订阅.中间可观察对象不会引起内存泄漏问题.

If everything that I want to do with an observable can be done in the view, then I virtually always use option 1. This covers most cases in my experience. You can always use intermediate observables to produce an observable that you can subscribe to in the view if you need to. Intermediate observables don't introduce memory leak concerns.

这篇关于Angular 5中的rxjs永久订阅的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆