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

ama*_*mat 3 typescript firebase-realtime-database angular

我开始玩Angular 6和Firebase。我想使用Hacker News API来显示提要(内容)。

我想返回一个Thing类数组的可观察对象。首先,我需要一个供稿ID数组,因此我打电话给Firebase来获取它们。然后,我想获取每个已有ID的提要,并将其作为可观察到的提要数组返回。

到目前为止,我的代码是这样的:

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([]);
        }
      })
    );
}
Run Code Online (Sandbox Code Playgroud)

我以为从数组来的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上调用订阅后,抛出该错误:

this.hackerNewsService.getThings(20).subscribe(console.log);
Run Code Online (Sandbox Code Playgroud)

我在以下代码段中重现了类似的情况:https : //stackblitz.com/edit/angular-8qtokd? file = src%2Fapp% 2Fapp.component.ts

rob*_*rob 5

尝试使用switchMapcombineLatest。例如

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([]);
                }
            })
        );
}
Run Code Online (Sandbox Code Playgroud)