在这些情况下是否需要订阅和删除可观察对象?

时间:2020-04-25 15:04:48

标签: angular rxjs ngrx rxjs-observables

我在这里考虑可观察物..

我想到了以下情况:

示例1) 在我使用NGRX的情况下,我可以正确创建所有架构,并为该特定商店创建选择器服务。

在服务中无法使用ngOnDestroy,因为它不是组件,并且我有以下问题,服务中是否存在内存泄漏?还是这项服务会自动销毁可观察物?

示例2) 在示例一中使用选择器,是否有必要订阅该选择器然后销毁它?

PEOPLE-SELECTORS.SERVICE

@Injectable({ providedIn: 'root' })
export class PeopleSelectorsService {
    constructor(private readonly store: Store<StoreState>) {}

    get error(): Observable<IRequestError> {
        return this.store.pipe(select(fromPeopleSelectors.getError));
    }

    get loading(): Observable<boolean> {
        return this.store.pipe(select(fromPeopleSelectors.getLoading));
    }

    get main(): Observable<IPeople> {
        return this.store.pipe(select(fromPeopleSelectors.getMain));
    }

    get total(): Observable<number> {
        return this.store.pipe(select(fromPeopleSelectors.selectTotal));
    }

    get all(): Observable<Array<IPeople>> {
        return this.store.pipe(select(fromPeopleSelectors.selectAll));
    }

    get allIds(): Observable<Array<string | number>> {
        return this.store.pipe(select(fromPeopleSelectors.selectIds));
    }
}

APP.COMPONENT

    ngOnInit(): void {
        this.peopleDispatchService.getAll();
        this.isLoading$ = this.peopleSelectorsService.loading;
}

<main [attr.isLoading]="isLoading$ | async">
    <ng-container></ng-container>
    <app-loading-container *ngIf="isLoading$ | async; else isMainController"></app-loading-container>

    <ng-template #isMainController>
        <app-user-talk-controller-container></app-user-talk-controller-container>
        <app-user-talk-container></app-user-talk-container>
    </ng-template>
</main>

2 个答案:

答案 0 :(得分:1)

那是完全正常的。 在没有订阅之前,您不会有任何内存泄漏。 async管道知道何时订阅和何时取消订阅,因此您不必担心忘记了订阅,一旦不再需要订阅,async就会取消订阅。

最好的方法是编写没有订阅IMHO的,充满管道的代码。

例如,在您的情况下,我将在app.component.ts中创建一个可观察的对象,将所有数据组合在一起,并具有一个可观察的对象。

ngOnInit(): void {
  this.data$ = combineLatest(
    this.peopleSelectorsService.loading,
    this.peopleSelectorsService.all,    
  ).map(([isLoading, records]) => ({isLoading, records}));
}
<ng-container *ngIf="data$ | async as data">
<main [attr.isLoading]="data.isLoading">
    <ng-container></ng-container>
    <app-loading-container *ngIf="data.isLoading; else isMainController"></app-loading-container>

    <ng-template #isMainController>
        <app-user-talk-controller-container></app-user-talk-controller-container>
        <app-user-talk-container [records]="data.records"></app-user-talk-container>
    </ng-template>
</main>
</ng-container>

我看到的主要好处是我们有单个订阅,订阅交集没有问题,因为当您有多个嵌套的async时,在模板中时不时会发现它们也可以相互依赖,并且他们将无法正常工作。只需一次订阅,就不会有这样的问题。

这也是我们在当前项目中所做的。 data$有时会很大,但是与模板或类中的多个订阅相比,感觉还是更好。

答案 1 :(得分:1)

服务中是否存在内存泄漏?还是这项服务会自动销毁可观察物?

销毁可观察物的概念没有任何意义。您破坏订阅(通过取消订阅),而不是观察到的东西。因此,不需要,您无需“破坏”服务中的可观察对象。

第二点,不。销毁组件后,异步管道会自动取消订阅。因此,只要您在html模板中使用async,就不必担心订阅和取消订阅

相关问题