当一个人依赖来自另一个

时间:2017-02-12 14:23:01

标签: angular observable angular2-observables

当一个observable运行时,它取决于来自另一个obseravble的数据,我无法弄清楚如何正确地处理这种依赖。

一个observable从Firebase获取数据,通过订阅它创建一个名为novelsRead:Array的简单数字数组

另一个observable从api获得响应,并且通过订阅它意味着过滤掉所有在小说中存在的idsRead []。

问题是,当响应来自api时,novelsRead []仍然是空的,因为Firebase尚未响应,因此不会从api响应中过滤掉任何内容。

以下代码:

导出类主页{

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;
            })
    })
}

我正在寻找最干净的解决方案,无论是使用事件,还是可观察的链或任何其他建议,例如将函数从构造函数移动到ngAfterViewInit,反之亦然。

我确实查看了使用combineLatest组合observable的代码示例,但发现语法非常复杂,并且想知道是否有更简洁的方法来实现我需要的东西,即使这涉及等待事件。

1 个答案:

答案 0 :(得分:4)

使用forkJoin可以为您提供帮助。 它允许仅在两个请求完成时处理结果: https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/operators/forkjoin.md

如果您的第二次请求取决于第一次回复,请使用switchMap

&#13;
&#13;
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}`));
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.3.0/Rx.min.js"></script>
&#13;
&#13;
&#13;