关于angular:将Array.map + Promise.all转换为Observable

Converting Array.map + Promise.all to Observable

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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 );
    }
}

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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 >,到目前为止,我有:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
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内部应该做的事情上。

我看到了这个质量检查,询问如何将Promise.all转换为Observable(Promise.all行为是否与RxJS Observables兼容?),答案是使用forkJoin,但也建议flatMap并链接到此帖子(RxJS Promise Composition( 传递数据)),但是这个问题与我的根本不一样。


您可以使用Observable.forkJoin,它将等待所有子可观察对象完成(与Promise.all相同)。

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

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

请参阅此Plunker演示。

抱歉,也许这有点晚了,因为它花了一些时间来找到有关rxjs5的新用法。