Подписки на RxJS Combine 2
У меня есть сервис, который выводит 2 наблюдаемые. 1 для получения текущего аутентифицированного пользователя, а другой для получения всех активных пользователей. На главном экране я хочу использовать обе эти наблюдаемые, это будет сделано (в настоящее время) путем подписки на обе эти наблюдаемые, однако первая наблюдаемая не всегда запускается. Я ищу решение для обеих наблюдаемых, чтобы испускать значение, прежде чем что-либо ошибается или загружается на страницу. Я попробовал forkjoin в своем примере ниже, но он не работает, я подозреваю, что это потому, что forkjoin ожидает, что что-то испустит, но ничего не излучает, но подписка на обе наблюдаемые действительно выводит данные, которые мне нужны. вот что я попробовал:
const tt = Observable.forkJoin(
this.auth.getActiveUsers().map((res) => res = res ),
this.auth.user.map((res) => res = res ),
);
console.log("running" );
tt.subscribe( (data) => {
console.log("data ", data );
console.log("data[0] ", data[0] );
console.log("data[1] ", data[1] );
},
err => console.error(err),
() => console.error("complete"),
);
и вот как выложены подписки в моем файле service.ts:
Filename: Service.ts
...
// first Observable
constructor( private afAuth: AngularFireAuth,
private db: AngularFirestore ) {
this.user = this.afAuth.authState.switchMap(user => {
if (user) {
return this.db.doc<iUser>(`users/${user.uid}`).valueChanges()
} else {
return Observable.of(null)
}
})
}
...
// second Observable
getActiveUsers(): Observable<iUser[]> {
return this.db.collection<iUser>('users').valueChanges().catch(this.catchError);
}
...
2 ответа
forkJoin
ожидает массив, поэтому я думаю, что именно поэтому он не работает в вашем коде:
const tt = Observable.forkJoin([
this.auth.getActiveUsers(),
this.auth.user
]);
// ...
Я полагаю, ваш auth.user
observable является горячим (не завершенным, когда передается значение), тогда как forkJoin выдает только тогда, когда все переданные наблюдаемые завершены. Не испускать значение, но завершить.
Если мое предположение верно, то, что вы можете сделать в этом случае, просто проходит auth.user.first()
который создаст полную наблюдаемую из исходной наблюдаемой, и ваш forkJoin будет работать как положено
Используйте mergeMap + forkJoin:
import { mergeMap } from 'rxjs/operators';
import { forkJoin, of } from 'rxjs';
const myPromise = val =>
new Promise(resolve =>
setTimeout(() => resolve(`Promise Resolved: ${val}`), 5000)
);
const source = of([1, 2, 3, 4, 5]);
const example = source.pipe(mergeMap(q => forkJoin(...q.map(myPromise))));
/*
output:
[
"Promise Resolved: 1",
"Promise Resolved: 2",
"Promise Resolved: 3",
"Promise Resolved: 4",
"Promise Resolved: 5"
]
*/
const subscribe = example.subscribe(val => console.log(val));