angular - Angular 5 中使用 rxjs 进行持久订阅

标签 angular rxjs

我对 Angular 5 中的 rxjs 还比较陌生,很难表述我的问题。不过我还是希望能得到一些提示。

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

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

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

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

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

a) 很简单,但是 b) 我经常遇到麻烦,想知道这是否是使用 Observables 的正确方法。

一个问题是,取消订阅在某些情况下变得很重要,并且错过取消订阅会导致每次更新可观察值时执行严重的垃圾。

另一方面,使用选项 a),当另一个组件正在更新底层数据时,我可能会错过一个组件中的一些更新。

是否有任何最佳实践可以避免所有这些陷阱?

最佳答案

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

  1. 使用async管道自动创建和删除订阅。如果您想严格根据可观察对象发出的数据进行 UI 更改,则异步管道可以在创建组件时轻松创建对给定可观察对象的订阅,并在组件销毁时删除这些订阅。这可以说是使用订阅的最简洁的方式。

举个例子:

@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 方法中取消订阅来管理组件中的订阅。当我需要访问组件代码中的订阅时,我倾向于采用这种约定。在每个使用订阅的组件中使用 ngOnInitngOnDestroy 方法会增加样板文件,但如果您需要在组件代码中进行订阅,则通常是必需的。
  • 例如:

    @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();
        }
    }
    
  • 通过使用限制操作(例如 first())来限制订阅生命周期。这是当您启动对 HttpClient observables 的订阅时默认执行的操作。这样做的好处是需要很少的代码,但它也可能导致订阅未清理的情况(例如,如果可观察对象从不发出)。
  • 如果我想要对可观察对象执行的所有操作都可以在 View 中完成,那么我几乎总是使用选项 1。这涵盖了我经验中的大多数情况。您始终可以使用中间可观察量来生成可观察量,如果需要,您可以在 View 中订阅该可观察量。中间可观察量不会引入内存泄漏问题。

    关于angular - Angular 5 中使用 rxjs 进行持久订阅,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49307098/

    相关文章:

    security - Angular 2 : sanitizing HTML stripped some content with div id - this is bug or feature?

    javascript - 在 Angular2 中使用动态组件加载器进行双向数据绑定(bind)

    javascript - Rxjs:使用 takeUntil(timer) 的 Observable 在计时器滴答后继续发射

    angular - 返回的 BehaviorSubject(作为 Observable)是否受 take(1) 或取消订阅的影响?

    javascript - RxJs:在 flatMapLatest 完成后访问 flatMapLatest 之前的数据

    javascript - angular-slickgrid,在选择编辑器更改事件时触发单元格编辑

    javascript - Angular 6 - 日期管道

    javascript - 类型 'Subscription' 缺少类型 'Observable<StringMap<any>>' 的以下属性

    javascript - 如何配置在 War 中运行的 Angular 5 项目?使用 Angular CLI

    javascript - 将动态数据传递给子组件