Почему подписка на BehaviourSubject asObservable никогда не срабатывает при завершении? - PullRequest
0 голосов
/ 16 мая 2018

Я использую Angular.У меня есть сервис, который я использую для хранения и получения данных из локального хранилища.Я сохраняю BehaviorSubject asObservable ().Код ниже:

import { Injectable} from "@angular/core";
import { BehaviorSubject } from 'rxjs/BehaviorSubject';

@Injectable()
export class NavigationStorageService {

  ModuleTitle = new BehaviorSubject<string>("");
  currentModuleTitle = this.ModuleTitle.asObservable();

  constructor() {}

  setModuleId(ModuleId) {
    localStorage.setItem('subModuleId', ModuleId)
    this.ModuleTitle.next(ModuleId);   
  }

  getModuleId() {
    this.ModuleTitle.next(localStorage.getItem('subModuleId'));
    return this.currentModuleTitle;
  }
}

Далее я получаю эти данные, используя код ниже:

getModuleId() {
  this._navigationStorageService.getModuleId()
    .subscribe(
      subModuleId => {
        this.subModuleId = subModuleId
      },
      error => {
        console.log(error)
      },
      () => console.log("getModuleId"));
}

Моя проблема в том, что я хочу выполнить другую функцию, когда наблюдаемая завершена, но эта наблюдаемая никогда не выполняетсязавершено, поэтому я не могу этого сделать.

() => console.log ("getModuleId") не показывает сообщение.

Как мне решить эту проблему?

В другой части моего приложения я использую Observable для получения запроса HttpClient, и он отлично работает.Я имею в виду onComplete пожары, как следует.

Я пытался использовать .finally ()

    getModuleId() {
    this._navigationStorageService.getModuleId()
        .finally(() => console.log("getModuleId"))
        .subscribe(
            subModuleId => {
                this.subModuleId = subModuleId
            },
            error => {
              console.log(error)
            },
            () => console.log("getModuleId"));
}

, но это не помогает.

Ответы [ 2 ]

0 голосов
/ 16 мая 2018

Субъекты заканчивают только тогда, когда вы говорите им завершить, звоня complete().

Вопрос здесь в том, чего вы пытаетесь достичь. Вполне возможно, что вы никогда не захотите завершить тему, поэтому вы никогда не позвоните this.ModuleTitle.complete(), но вы все равно захотите отправить complete уведомление "потребителям" currentModuleTitle.

Это означает, что вы можете использовать оператор take(1), который принимает только одно значение и сразу завершает цепочку (не нужно использовать asObservable).

currentModuleTitle = this.ModuleTitle.take(1);

Теперь каждый раз, когда вы делаете currentModuleTitle.subscribe(), вы сразу получаете одно значение и завершаете. Имейте в виду, что BehaviorSubject сначала выдает свое сохраненное значение, поэтому все потребители currentModuleTitle фактически получат только кэшированное значение и никаких дальнейших обновлений.

0 голосов
/ 16 мая 2018

Вы используете плохо наблюдаемый объект.Когда вы используете метод getModuleId () для получения элемента localStorage, вы сразу получаете это значение, тогда наблюдаемое не имеет смысла.

 import { Injectable} from "@angular/core";
import { BehaviorSubject } from 'rxjs/BehaviorSubject';

@Injectable()
export class NavigationStorageService {

  ModuleTitle = new BehaviorSubject<string>("");
  currentModuleTitle = this.ModuleTitle.asObservable();

  constructor() {}

  setModuleId(ModuleId) {
    localStorage.setItem('subModuleId', ModuleId)
  }

  getModuleId(id) {
    return localStorage.getItem(id);
  }
}
...