如何从一个可观察对象数组中返回一个可观察对象

4

我开始尝试使用Angular 6和Firebase。我想使用Hacker News API来显示feeds(内容)。

我想返回一个Thing类的可观察数组。首先,我需要一个feed ID的数组,所以我调用Firebase来获取这些ID。然后,我想获取我已经拥有的每个ID的feeds,并将其作为单个可观察的feeds数组返回。

到目前为止,我的代码如下:

getThings(limit: number): Observable<any> {
  return this.db.list('/v0/beststories', ref => ref.limitToFirst(limit).orderByKey())
    .valueChanges() // returns an Observable of IDs
    .pipe(
      flatMap(itemIds => {
        if (itemIds.length > 0) {
          let sources = itemIds.map(itemId => defer(() => {
            let pathOrRef = '/v0/item/' + itemId;
            return this.db.object(pathOrRef).valueChanges();
          }));
          // sources are the array of Observables
          return forkJoin(sources);
        } else {
          return Observable.create([]);
        }
      })
    );
}

我认为从数组中进行flatMapping会是解决方法,但是我得到了错误信息:You provided an invalid object where a stream was expected. You can provide an Observable, Promise, Array, or Iterable

我尝试按照RxJs Array of Observable to Array中的方式做,但是我不知道哪里出错了。

在返回的Observable上调用subscribe后会抛出错误。

this.hackerNewsService.getThings(20).subscribe(console.log);

我在下面的代码片段中重现了类似的情况:https://stackblitz.com/edit/angular-8qtokd?file=src%2Fapp%2Fapp.component.ts。请注意,这个链接包含了一个示例代码,涉及到IT技术相关内容。

1
我认为flatMap返回一个observable,就像你在else中所做的那样。因此,您需要使用of或在flatMap内部进行另一个http调用并返回observable。 - windmaomao
错误抛出在哪里?它是不是在这个flatMap中? - martin
@windmaomao,我不确定你所说的“flatMap内部的另一个调用”具体是什么意思。你能否提供一些代码片段来说明? - amalgamat
1个回答

7
尝试使用 `switchMap` 和 `combineLatest`。例如:
import {combineLatest, Observable} from 'rxjs';
import {map, switchMap} from 'rxjs/operators';

function getThings(limit: number): Observable<any> {
    return this.db.list('/v0/beststories', ref => ref.limitToFirst(limit).orderByKey())
        .valueChanges() // returns an Observable of IDs
        .pipe(
            switchMap(itemIds => {
                if (itemIds.length > 0) {
                    let sources = itemIds.map(itemId => {
                        let pathOrRef = '/v0/item/' + itemId;
                        return this.db.object(pathOrRef).valueChanges();
                    });
                    // sources are the array of Observables
                    return combineLatest(sources);
                } else {
                    return Observable.create([]);
                }
            })
        );
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接