将Array.map + Promise.all转换为Observable

时间:2017-09-14 02:55:09

标签: angular reactjs rxjs observable

我有返回Promises的Vanilla.js(TypeScript)HTTP客户端,如下所示:

class Person {
    name: string;
    id: number;
    friendsIds: number[];
}

class MyClient {

    getPersonInfo(personId: number): Promise<Person> {

        return fetch( '/people/' + personId)
            .then( r => r.json() as Person );
    }
}

我的显示代码获取每位朋友的详细信息,如下所示:

refresh(): void {

    client.getPersonInfo( 123 )
        .then( (person: Person) => {

            // array-of-promises:
            let friendsDetailsPromises: Promise<Person>[] = person.friendsIds.map( friendId => client.getPersonInfo( friendId  ) );

            // promise-of-array:
            let friendsDetailsAll     : Promise<Person[]> = Promise.all( friendsDetailsPromises );

            return friendsDetailsAll;
        } )
        .then( (friendsDetails: Person[]) => {

            // (do stuff for each Person)
        } )
        .catch( reason => console.error( reason ) );
}

我试图将其转移到Angular 2的内置HTTP客户端,该客户端返回Observable<T>而不是Promise<T>,到目前为止,我有:

class MyClient {

    private http: HttpClient; 

    getPersonInfo(personId: number): Observable<Person> {

        return this.http.get<Person>( '/person/' + personId );
    }
}

refresh(): void {

    client.getPersonInfo( 123 )
        .flatMap( (person: Person) => {

            // ...now what?
        } )
        .subscribe(
            (friendsDetails: Person[]) => {

            // (do stuff for each Person)
            },
            err => console.error( err )
        )
    );
}

我仍然坚持我应该在flatMap内做的事情。

我看到此QA询问有关将Promise.all转换为ObservablePromise.all behavior with RxJS Observables?)的问题,答案是使用forkJoin,但也建议flatMap并链接这个帖子(RxJS Promise Composition (passing data)),但这个问题根本不像我的。

1 个答案:

答案 0 :(得分:2)

您可以使用等待所有子可观察量完成的Observable.forkJoin(与Promise.all相同)。

我发现以下语法有效(可能不是最好的,等待建议

this.http.get('list.json').switchMap(res => {                   
  return Observable.forkJoin(res.map(item => this.http.get(item + '.json')));  
})

请参阅 Plunker demo

对不起,也许这有点晚了,因为花了一些时间才找到关于rxjs5的新用法。