当一个依赖于另一数据时处理可观察对象 [英] handling observables when one is dependent on data from another

查看:58
本文介绍了当一个依赖于另一数据时处理可观察对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当一个可观察对象运行时,它依赖于来自另一个可观察对象的数据,我无法弄清楚如何正确处理这种依赖关系.

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.

一个可观察对象从Firebase获取数据,并通过订阅创建一个简单的数字数组,称为NovelsRead:数组

One observable gets data from Firebase and by subscribing it creates a simple number array called novelsRead: Array

另一个可观察对象从api获得响应,并且通过订阅该响应可以过滤掉所有小说中存在id的记录.

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[].

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

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.

以下代码:

导出类首页{

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,反之亦然.

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.

我确实看过使用CombineLatest组合可观察对象的代码示例,但是发现语法非常复杂,并且想知道是否有一种更干净的方法来满足我的需求,即使这涉及到等待事件.

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.

推荐答案

使用forkJoin应该会对您有所帮助. 它仅在两个请求都完成时才允许处理结果: https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/operators/forkjoin.md

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

或者如果您的第二个请求依赖于第一个响应-请使用switchMap

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>

这篇关于当一个依赖于另一数据时处理可观察对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆