RxJS Предмет / Наблюдаемая проблема - PullRequest
0 голосов
/ 24 мая 2018

Я пытаюсь преобразовать функцию Angular в наблюдаемый шаблон, поскольку его текущая реализация имеет некоторую асинхронность.Для целей этого обсуждения возьмем этот простой пример.

aFunction(x: boolean){
    if(x){
        // ... do something asynchronous based on the value of x
    }
}

Преобразование его в Observable можно выполнить следующим образом:

anObservableFunction(x: boolean): Observable<any> {
    const result = new Subject();
    if(x){
        // ... do something asynchronous based on the value of x
        // ... where once the actual value you want to return to 
        // the subscribing functions, you can pass in the 
        // result.next(value);
        // result.complete();
    }
    return result.asObservable();
}

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

anObservableFunction(x: boolean): Observable<any> {
    const result = new Subject();
    if(x){
        // ... do something asynchronous based on the value of x
        // ... where once the actual value you want to return to 
        // the subscribing functions, you can pass in the 
        // result.next(value);
        // result.complete();
    } else {
        // here
    }
    return result.asObservable();
}

Если используется обычный субъект, несомненно, функции подписки не получат никакого значения, поскольку порядок событий будет следующим:

  • Функция вызывается
  • Тема создана
  • Значение установлено
  • Вызывающая функция подписывается, таким образом, получая значения только после наступления этого события

А если используются BehaviorSubject или ReplaySubject, ихпервоначальное / созданное значение будет сохранено, что приведет к ненужному срабатыванию события подписки?

1 Ответ

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

Вы правы, что при использовании субъекта возникает проблема, если значения передаются синхронно.Недостатком BehaviorSubject является наличие ненужного начального значения, но ReplaySubject на самом деле его не имеет и будет работать, но он также будет воспроизводить это значение, если кто-то подпишется позже, на что вы можете не захотеть.

Простым трюком было бы отсрочить синхронное излучение с помощью галочки:

setTimeout(() => result$.next(42), 0);

Однако вы также можете вернуть наблюдаемое напрямую и избегать использования объекта:

foo(x) {
  if(x) {
    return callRemoteEndpoint();
  }

  return of(42);
} 
...