RxJS 6: Почему вызывать ценность для BehaviorSubject - это плохо? (согласно правилу lint без значения предмета) [дубликат]

Мое обходное решение:

function add(a, b, precision) {
    var x = Math.pow(10, precision || 2);
    return (Math.round(a * x) + Math.round(b * x)) / x;
}

precision относится к числу цифр, которые вы хотите сохранить после десятичной точки во время добавления.

85
задан Baconbeastnz 7 May 2016 в 14:54
поделиться

5 ответов

A Subject или Observable не имеет текущего значения. Когда значение испускается, оно передается подписчикам, а Observable выполняется с ним.

Если вы хотите иметь текущее значение, используйте BehaviorSubject, который предназначен именно для этой цели. BehaviorSubject сохраняет последнее испущенное значение и немедленно отправляет его новым подписчикам.

Он также имеет метод getValue() для получения текущего значения.

160
ответ дан Günter Zöchbauer 4 September 2018 в 09:22
поделиться

Единственный способ, которым вы должны получать значения «из» наблюдаемого / субъекта, подписаться!

Если вы используете getValue(), вы делаете что-то императив в декларативной парадигме. Он находится в качестве выходного люка, но 99,9% времени вы НЕ должны использовать getValue(). Есть несколько интересных вещей, которые сделают getValue(): он выдает ошибку, если объект был отписано, это не позволит вам получить значение, если объект мертв, потому что он ошибочен и т. Д. Но, опять же, он там в качестве выходного люка для редких обстоятельств.

Существует несколько способов получить последнее значение от объекта или наблюдаемого по методу «Rx-y»:

  1. Используя BehaviorSubject: Но фактически подписывается на него . Когда вы впервые подписываетесь на BehaviorSubject, он будет синхронно отправлять предыдущее значение, полученное или инициализированное с помощью.
  2. Использование ReplaySubject(N): это будет кешировать N значения и воспроизводить их для новых подписчиков.
  3. A.withLatestFrom(B): Используйте этот оператор, чтобы получить последнее значение от наблюдаемого B, когда наблюдается наблюдаемое A. Дает вам оба значения в массиве [a, b].
  4. A.combineLatest(B): Используйте этот оператор, чтобы получать самые последние значения из A и B каждый раз, когда A или B излучает. Дает вам оба значения в массиве.
  5. shareReplay(): Делает наблюдаемую многоадресную передачу через ReplaySubject, но позволяет повторить наблюдаемую при ошибке. (В основном это дает вам такое поведение кэширования с обещанием).
  6. publishReplay(), publishBehavior(initialValue), multicast(subject: BehaviorSubject | ReplaySubject) и т. Д. Другие операторы, которые используют BehaviorSubject и ReplaySubject. Разные вкусы одного и того же, они в основном многоадресный источник, наблюдаемый путем перенаправления всех уведомлений через предмет. Вы должны позвонить connect(), чтобы подписаться на источник с объектом.
74
ответ дан forivall 4 September 2018 в 09:22
поделиться

У меня была схожая ситуация, когда поздние подписчики подписывались на Субъект после того, как его значение прибыло.

Я нашел ReplaySubject , который похож на BehaviorSubject, работает как шарм в этом случае. И вот ссылка на лучшее объяснение: http://reactivex.io/rxjs/manual/overview.html#replaysubject

4
ответ дан Kfir Erez 4 September 2018 в 09:22
поделиться

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

import {Storage} from './storage';
import {Injectable} from 'angular2/core';
import {Subject}    from 'rxjs/Subject';

@Injectable()
export class SessionStorage extends Storage {

  isLoggedIn: boolean;

  private _isLoggedInSource = new Subject<boolean>();
  isLoggedIn = this._isLoggedInSource.asObservable();
  constructor() {
    super('session');
    this.currIsLoggedIn = false;
  }
  setIsLoggedIn(value: boolean) {
    this.setItem('_isLoggedIn', value, () => {
      this._isLoggedInSource.next(value);
    });
    this.isLoggedIn = value;
  }
}

Компонент, который нуждается в текущем значении, может просто получить к нему доступ из службы, то есть:

sessionStorage.isLoggedIn

Не уверен, что это правильная практика :)

2
ответ дан Molp Burnbright 4 September 2018 в 09:22
поделиться

Вы можете сохранить последнее испущенное значение отдельно от наблюдаемого. Затем прочитайте его, когда это необходимо.

let lastValue: number;

const subscription = new Service().start();
subscription
    .subscribe((data) => {
        lastValue = data;
    }
);
-2
ответ дан Slawa 4 September 2018 в 09:22
поделиться