Почему angular BehaviorSubject запоминает последний объект, переданный после отмены подписки?

У меня есть служба с элементом behaviorSubject, например:

 public _changeAlert = new BehaviorSubject<myMsg>(null);
 public changeAlert = this._changeAlert.asObservable();
 public sendAlert(msg$: string){
     this._changeAlert.next(msg$);
   }

И иметь подписчика ReceiverComponent.ts

 alerterPointer: any;
 constructor(private alertSrv: alertService){
     this.alerterPointer = this.alertSrv.changeAlert.subscribe(msg$ => {console.info(msg$)});

   }
}
ngOnDestroy(){
     this.alerterPointer.unsubscribe();

компонент, отправляющий / транслирующий предупреждение alertter.ts

  sendAlert(){
    this.alertSrv.sendAlert('Hello world');
}

Моя проблема в том, что даже после отказа от подписки, если я перейду к другому компоненту и вернусь к ReceiverComponent.ts, он фактически получит "hello world" вместо нулевого значения начальной подписки. Другими словами, он запоминает последнее переданное предупреждение.

Как мне избежать этой утечки? ... Я использую этот подход во всем своем проекте, и у меня есть существенные утечки, связанные с этим поведением.

(пожалуйста, не помечайте его как дублированный, я проверил аналогичный вопрос, но он не решает ту же проблему)

Благодарность !


person Mike Gmez    schedule 24.12.2019    source источник
comment
Так что вы ожидаете, что он будет нулевым? где определяется BehaviorSubject? какой-то сервис вне компонентов? похоже, это работает так, как было задумано.   -  person Sergey Rudenko    schedule 25.12.2019
comment
Вы указываете эту услугу в качестве поставщика в модуле, объявляющем эти компоненты? Не могли бы вы опубликовать код этого модуля и службы с декоратором и его метаданными.   -  person nullptr.t    schedule 25.12.2019
comment
Спасибо вам всем. На мой взгляд, bs похожи на вещателей на angularJS, и я подумал, что будет более изящный способ (стиль сборщика мусора) избавиться от этих подписок. Я уже вызывал службу с нулевым значением при уничтожении, таким образом, последний полученный вызов был вызовом с нулевым значением, и в этом случае у меня есть логика, чтобы игнорировать его, но, опять же, всегда думал, что есть более элегантный способ делать это.   -  person Mike Gmez    schedule 25.12.2019


Ответы (3)


Если вам нужно текущее значение, вы можете использовать Subject вместо behaviorSubject

person UmeshB    schedule 25.12.2019

Здесь происходит то, что ваш BehaviourSubject существует в вашем сервисе. В качестве очень простого обходного пути вы можете создать новое значение на вашем onDestroy, чтобы заставить BehaviourSubject иметь значение null.

 this._changeAlert.next(null);

Так в следующий раз вместо Hello World вы получите null

person guzmanoj    schedule 25.12.2019

Вы описываете, как работает BehaviorSubject. BehaviorSubject сохраняет последнее переданное значение. Каждый раз, когда новый Observer подписывается, он немедленно получает «текущее значение» от BehaviorSubject. Если вам не нужен этот переход на Subject, как уже @UmeshB, @ [Jose Guzman] и @ [Ashot Aleqsanyan] предложили вам.

person wnvko    schedule 25.12.2019