问题
When one observable runs it is depedent on data which comes from another obseravble and I can't work out how to hanlde this dependency correctly.
One observable gets data from Firebase and by subscribing it creates a simple number array called novelsRead: Array
The other observable gets a response from an api and by subscribing it is meant to filter out all the records who's ids are present in novelsRead[].
The issue is, when a response comes from the api, novelsRead[] is still empty because Firebase hasn't responded yet so nothing will be filtered from the api response.
Code below:
export class HomePage {
currentnovels: any;
novels: any;
unreadnovels: any;
nextnovels: any;
novel: any;
resultsPageNumber: number = 1;
novelFullPosterPath: any;
novelsread: Array<number> = [];
private basePosterUrlMedium = 'http://image.novels.org/t/p/w500';
private basePosterUrlSmall = 'http://image.novels.org/t/p/w185';
constructor(private http: Http,
private novelsApi: NovelsApiService,
private dataService: DataService,
) {
//this takes data from Firebase and pushes it to simple array of ids (numbers)
this.dataService.list('novels-read')
.subscribe(data => {
data.map(results => {
this.novelsread.push(results.novelsId);
})
})
}
ngAfterViewInit() {
this.novelsApi.getnovelsByPage(this.resultsPageNumber)
.subscribe(data => {
this.novels = data.results;
this.novels.map(data => {
data.full_poster_path = this.basePosterUrlMedium + data.poster_path;
return data;
})
.filter(data => {
let found = this.novelsread.indexOf(data.id);
//It seems when the api responds, this.novelsRead is still empty [] because Firebase has not responded yet
console.log("this novelsread[0] is ", this.novelsread[0]);
console.log("data.id found is ", found);
return data;
})
})
}
I am looking for the cleanest solution whether that's using events, or observable chains or any other suggestions like moving functions from the constructor to ngAfterViewInit and vice versa.
I did look at code examples for combining observables using combineLatest but found the syntax very convoluted and wondered if there is a cleaner way of achiveing what I need, even if that involves waiting for events.
回答1:
Using forkJoin
should help you.
It allows to handle result only when both requests complete:
https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/operators/forkjoin.md
OR if your 2nd request depends on 1st response - use switchMap
const request1$ = Rx.Observable.of('response1').delay(2000);
const request2$ = Rx.Observable.of('response2').delay(100);
Rx.Observable.forkJoin(request1$, request2$)
.subscribe(res => console.log(`forkJoin: ${res}`));
request1$.switchMap(res1 => {
console.log(`switchMap: ${res1}`);
return request2$;
}).subscribe(res2 => console.log(`switchMap: ${res2}`));
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.3.0/Rx.min.js"></script>
来源:https://stackoverflow.com/questions/42188732/handling-observables-when-one-is-dependent-on-data-from-another