Обязательно ли в этих случаях подписываться и удалять наблюдаемые?

Я здесь думаю о наблюдаемых ..

И я представил себе следующие ситуации:

Пример 1) В моем случае, когда я использую NGRX, я правильно создаю всю архитектуру и создаю службу выбора для этого конкретного магазина.

В службе невозможно использовать ngOnDestroy, потому что это не компонент, и у меня возникает следующий вопрос: есть ли утечка памяти в службе? Или этот сервис автоматически уничтожает наблюдаемые?

Пример 2) Используя селекторы в первом примере, нужно ли подписаться на этот селектор, а затем уничтожить его?

ПЕРСОНАЛИЗАЦИЯ.СЕРВИС

@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>

person Community    schedule 25.04.2020    source источник


Ответы (2)


Это совершенно нормально. Пока у вас нет подписки, у вас не будет утечек памяти. async pipe знает, когда подписаться и когда отказаться от подписки, поэтому вам не стоит беспокоиться о забытых подписках, async отменит подписку, как только подписка больше не понадобится.

Лучший способ - написать код, полный каналов, без подписки. ИМХО.

Например, в вашем случае я бы создал одну наблюдаемую в 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$ довольно велико, но все же кажется лучше, чем несколько подписок в шаблоне или в классе.

person satanTime    schedule 25.04.2020
comment
Какая подписка ИМХО? - person ; 26.04.2020
comment
В моем скромном мнении en.wiktionary.org/wiki/in_my_humble_opinion#English - person satanTime; 26.04.2020

есть ли утечка памяти в сервисе? Или этот сервис автоматически уничтожает наблюдаемые?

Концепция уничтожения наблюдаемых на самом деле не имеет смысла. Вы уничтожаете подписки (отказавшись от подписки), а не наблюдаемые объекты. Так что нет необходимости «уничтожать» наблюдаемые в вашем сервисе.

Что касается вашего второго пункта, нет. Асинхронный конвейер автоматически отменяет подписку при уничтожении компонента. Итак, пока вы используете async в шаблоне html, вам не нужно беспокоиться о подписке и отказе от подписки.

person ShamPooSham    schedule 25.04.2020