如何通过第二次调用将 Observable 与信息合并
How to consolidate an Observable with informations by a second calls
出于教育目的,我正在尝试调用检索帖子列表的服务,对于每个 post,我想再次调用此服务以获取评论列表.
我正在使用来自 https://jsonplaceholder.typicode.com/posts
的数据
首先是我为此服务提取的模型:
export interface Post {
userId: number;
id: number;
title: string;
body: string;
comments: PostComment[];
}
export interface PostComment {
postId: number;
id: number;
name: string;
email: string;
body: string;
}
这是我目前的状态。我的目标是 Observable<Post>
正确填充 属性 comments
。
export class PostCommentsCombination implements OnInit {
constructor(private http: HttpClient) {}
posts$?: Observable<Post[]>;
ngOnInit(): void {
this.posts$ =this.http.get<Post[]> ('https://jsonplaceholder.typicode.com/posts/').pipe(
switchMap((posts) =>
posts.map((post) =>
this.http.get<PostComment[]>(`https://jsonplaceholder.typicode.com/posts/${post.id}/comments`).pipe(
map((comments) => {
post.comments = comments;
return post;
})
)
)
)
);
}
}
但是它说不能将Observable<Observable<Post>>
转换成Observable<Post[]>
。我不能怪他,但我不确定如何解决这个问题?
posts.map((post) => ...
基本上是获取每个 post 并将其映射到一个 Observable。所以你最终得到了一个 Observables 数组。你想要做的是解析数组中的每个 Observable 以获得你想要的输出。如果您熟悉 promises,您希望 rxjs 等效于 Promise.all,它本质上是 forkJoin - 请参阅此 post
可以 forkJoin
请求评论,更新 post.comments
字段和 return post
返回:
this.posts$ = this.http
.get<Post[]>('https://jsonplaceholder.typicode.com/posts/')
.pipe(
switchMap(posts =>
forkJoin(
posts.map(post =>
this.http
.get<PostComment[]>(`https://jsonplaceholder.typicode.com/posts/${post.id}/comments`)
.pipe(map(comments => {
post.comments = comments;
return post;
}))
)
)
)
);
我会尝试这样的事情:
ngOnInit(): void {
const postsUrl = 'https://jsonplaceholder.typicode.com/posts/';
this.posts$ = this.http.get<Post[]>(postsUrl).pipe(
map(posts => posts.map(post =>
this.http.get<PostComment[]>(`${postsUrl}${post.id}/comments`).pipe(
map(comments => ({...post, comments}))
)
)),
switchMap(postObservables => forkJoin(postObservables))
);
}
出于教育目的,我正在尝试调用检索帖子列表的服务,对于每个 post,我想再次调用此服务以获取评论列表.
我正在使用来自 https://jsonplaceholder.typicode.com/posts
的数据首先是我为此服务提取的模型:
export interface Post {
userId: number;
id: number;
title: string;
body: string;
comments: PostComment[];
}
export interface PostComment {
postId: number;
id: number;
name: string;
email: string;
body: string;
}
这是我目前的状态。我的目标是 Observable<Post>
正确填充 属性 comments
。
export class PostCommentsCombination implements OnInit {
constructor(private http: HttpClient) {}
posts$?: Observable<Post[]>;
ngOnInit(): void {
this.posts$ =this.http.get<Post[]> ('https://jsonplaceholder.typicode.com/posts/').pipe(
switchMap((posts) =>
posts.map((post) =>
this.http.get<PostComment[]>(`https://jsonplaceholder.typicode.com/posts/${post.id}/comments`).pipe(
map((comments) => {
post.comments = comments;
return post;
})
)
)
)
);
}
}
但是它说不能将Observable<Observable<Post>>
转换成Observable<Post[]>
。我不能怪他,但我不确定如何解决这个问题?
posts.map((post) => ...
基本上是获取每个 post 并将其映射到一个 Observable。所以你最终得到了一个 Observables 数组。你想要做的是解析数组中的每个 Observable 以获得你想要的输出。如果您熟悉 promises,您希望 rxjs 等效于 Promise.all,它本质上是 forkJoin - 请参阅此 post
可以 forkJoin
请求评论,更新 post.comments
字段和 return post
返回:
this.posts$ = this.http
.get<Post[]>('https://jsonplaceholder.typicode.com/posts/')
.pipe(
switchMap(posts =>
forkJoin(
posts.map(post =>
this.http
.get<PostComment[]>(`https://jsonplaceholder.typicode.com/posts/${post.id}/comments`)
.pipe(map(comments => {
post.comments = comments;
return post;
}))
)
)
)
);
我会尝试这样的事情:
ngOnInit(): void {
const postsUrl = 'https://jsonplaceholder.typicode.com/posts/';
this.posts$ = this.http.get<Post[]>(postsUrl).pipe(
map(posts => posts.map(post =>
this.http.get<PostComment[]>(`${postsUrl}${post.id}/comments`).pipe(
map(comments => ({...post, comments}))
)
)),
switchMap(postObservables => forkJoin(postObservables))
);
}