如何从可观察变量数组中返回一个可观察变量 [英] How to return an observable from an array of observables

查看:60
本文介绍了如何从可观察变量数组中返回一个可观察变量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I started to play around with Angular 6 and Firebase. I wanted to use Hacker News API for displaying feeds (things).

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

I wanted to return an observable of an array of Thing class. Firstly I need an array of feed IDs, so I make a call to Firebase to fetch these. Then I wanted to fetch the feeds for each ID I already have, and return it as a single observable of an array of feeds.

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

What I have so far is the code like this:

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.

I thought that flatMapping from the array would be the solution, but I get You provided an invalid object where a stream was expected. You can provide an Observable, Promise, Array, or Iterable.

我试图以与

I tried to do this in similar way as it's in RxJs Array of Observable to Array , but I don't know where I made a mistake.

调用返回的Observable上的订阅后引发错误:

The error is thrown after invoking subscribe on the returned Observable:

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

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

The similar situation I reproduce in the following snippet: https://stackblitz.com/edit/angular-8qtokd?file=src%2Fapp%2Fapp.component.ts

推荐答案

尝试使用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([]);
                }
            })
        );
}

这篇关于如何从可观察变量数组中返回一个可观察变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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