我开始尝试使用 Angular 6 和 Firebase。我想使用 Hacker News API 来显示提要(事物)。
我想返回一个 Thing 类数组的可观察对象。首先,我需要一组提要 ID,因此我调用 Firebase 来获取这些 ID。然后我想获取我已有的每个 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([]);
}
})
);
}
我认为数组中的 flatMapping 将是解决方案,但我得到 您提供了一个无效的对象,其中需要一个流。您可以提供 Observable、Promise、Array 或 Iterable
。
我尝试以与 RxJs Array of Observable to Array 中类似的方式执行此操作, 但我不知道我在哪里犯了错误。
在返回的 Observable 上调用订阅后抛出错误:
this.hackerNewsService.getThings(20).subscribe(console.log);
我在以下片段中重现了类似情况:https://stackblitz.com/edit/angular-8qtokd?file=src%2Fapp%2Fapp.component.ts
最佳答案
尝试使用 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([]);
}
})
);
}
关于angular - 如何从可观察对象数组中返回可观察对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51231667/