2016-11-17 4 views
2

У меня есть AuthService, который извлекает данные Observable<auth> из Firebase и помещает их в общедоступную переменную auth$.Совместное использование Auth Наблюдаемое значение между компонентами без его выполнения несколько раз

Где-то в моем приложении мне нужно несколько компонентов для доступа к этому значению auth$, чтобы проверить его содержимое.

Я сейчас просто делаю this.authService.auth$.subscribe(auth => this.auth = auth) в компонентах.

  1. Означает ли это, что я выполнение fetch data from Firebase несколько раз?

  2. Если да, то я должен определить аутентификации $ как субъект/BehaviorSubject, подписаться на услугу и передавать данные с .next?

+0

FIrebase имеет некоторое внутреннее кэширование, поэтому оно не должно быть проблемой. Вы можете проверить сетевой трафик в DevTools> Network> WebSockets ... – Sasxa

+0

Хорошо, что хорошо знать о Firebase, я проверю это. Но как насчет http-звонка? (что-то без кэширования) – Tom

+0

Вы можете использовать ['share()'] (http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#instance-method-share) оператор 'this. authService.auth $ = Observable.of ('whatever'). share() 'и он должен быть общим для всех подписчиков ... – Sasxa

ответ

3

По умолчанию наблюдаемый не включен многоадресной рассылкой. Это означает, что несколько подписей будут генерировать собственный поток. Поскольку вы не хотите повторно запрашивать учетные данные для аутентификации на подписку, вам необходимо сделать свой мультикаст с исходным потоком. Это делается с использованием, например, оператора share(), который сделает поток горячим по первой подписке и внутренне сохранит refcount для всех следующих подписчиков.

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

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

Так что ваш код будет выглядеть следующим образом:

const authStream = this.authService.auth$.shareReplay(1); 

// component 1 
const myAuthDisposable = authStream.subscribe(auth => this.auth = auth) 

// component 2 
const myAuthDisposable = authStream.subscribe(auth => this.auth = auth) 
+1

Хорошо спасибо! Я не знал 'shareReplay()'. Кажется, он был удален. Он говорит [здесь] (http://stackoverflow.com/questions/35246873/sharereplay-in-rxjs-5), что его следует заменить на .publishReplay (1) .refCount() '. Вы согласны? – Tom

+0

Длительное обсуждение проблемы github, похоже, говорит о том, что поведение '.publishReplay (1)' будет таким же в rxjs5, что и в rxjs4, поэтому использование в сочетании с 'refCount()', похоже, сработает. Не проверял это сам, хотя. –